Skim v1.0.9 — "Nice Try, Phish" 🎣
The one where Skim learns to smell a phishing email from across the room and does it all locally, offline, without phoning a single reputation service. Your inbox, now with a healthy sense of suspicion.
New
-
Phishing detection, built right in. Skim now quietly vets every message for the classic tells and warns you before you click something you'll regret.
Sender checks reads SPF / DKIM / DMARC results, catches "reply goes to a totally different domain" tricks, spots when the friendly display name hides a stranger's address, and flags lookalike domains (paypa1.com, we see you).
Link checks a link that says one thing but opens another, user@evil.com sleight of hand, and raw-IP links get stopped cold. Shorteners, plain http, punycode, weird ports and endless subdomains get side-eye too but only when the sender already looks shady, so your newsletters full of tracking redirects don't set off alarms.
A link gate click a suspicious link and Skim tells you where it actually goes and lets you bail or proceed. No more mystery destinations.
"Check for phishing" with AI one tap to have Skim AI read the sender, the auth results, and the links, then explain the whole thing in plain language.
All of it deterministic, all of it offline. No thresholds to tune, no data leaving your machine.
Skim v1.0.23 — "Press the button, something happens" 🔘
The one where the Restart to update button admits it heard you. Turns out shipping an updater whose only feedback is "trust me bro" was a bold choice.
Fixed
"Restart to update" now actually restarts. Before: you clicked, nothing happened, you clicked four more times out of spite, and a minute later the app quietly closed on its own. The click was stuck waiting on a database write that the mail sync had no intention of letting go of. Now the banner flips to "Installing update " the instant you click it and stops being a button, so those four extra clicks can't each launch their own installer racing the other three for your install folder.
A clean exit before the installer takes over. The updater ends this process with process::exit(0) no goodbyes. So on the way out Skim now parks the sync engines and folds the write-ahead log back into the database, instead of leaving a few megabytes of unfinished business for the next build to untangle on its very first query.
The message list stopped lying to you. "Nothing to skim" used to mean either "this folder is empty" or "the read blew up and nobody told you". Guess which one you got after updating. It now says "Couldn't load retry" and gives you the retry, and only claims a folder is empty when it actually read the folder.
Sync events that arrive before the app is ready no longer vanish. The mail engine starts syncing in Rust before the window has finished asking who owns which mailbox; the first "there's new mail" used to land in the void, and the next scheduled one was five minutes away. They're collected now.
Reopening from the tray does something again. Hiding to the tray only hides the webview no frontend code re-runs on the way back, so a list left empty by a failed read stayed empty no matter how many times you reopened it. The window now says "I'm back", and a broken view puts itself right.
Housekeeping
Skim v1.0.5 — "One Inbox to Rule Them All" 🪄
The one where all your mailboxes finally stop pretending they don't know each other. Connect five accounts, get one tidy stream of mail sorted by date. Revolutionary concept: everything in one place.
New
"All inboxes" view pick All inboxes in the account switcher and every connected mailbox pours into a single, date-sorted list of messages and threads. No more clicking between accounts like it's 2009.
From picker in compose replying or writing fresh from the unified view? Skim now lets you choose which account it goes out from, so your work self doesn't accidentally email your mom's book club.
Skim v1.0.22 — "Ask the MX, not the vibes" 🛂
The one where Skim stops pretending that Microsoft owns exactly four domains on the entire internet.
New
Work & school accounts are finally recognized. If your company lives on Exchange Online, Skim now asks your domain's MX records who really hosts the mail. Everything Microsoft runs answers on *.protection.outlook.com, so the sign-in button that actually works shows up on its own no more falling into the manual IMAP/SMTP form to guess hostnames that were never going to connect. (Yes, hotmail.de too. Sorry it took a whole minor version to notice Germany exists. )
Behind a mail gateway? Proofpoint and Mimecast tenants don't advertise Microsoft in MX at all, so unknown domains now get one quiet "Work or school account?" line instead of a shrug. One line. We counted.
The DNS probe goes through the machine's own resolver (DnsQuery_W) your domain never visits a third party, results are memoized, the whole thing is capped at 3 seconds, and if it fails the screen looks exactly like it did before.
Fixed
Skim v1.0.18 — "Mind the closing boundary" 🧱
The one where we stop blaming you for emails that render as a beautiful, pristine, completely empty rectangle. Turns out it was us. Well it was the sender's mailer. But we fixed it anyway.
Fixed
Blank emails are no longer blank. Some mailers finish a message on the last base64 chunk and just walk away, never writing the closing --boundary--. The MIME parser reads that as "this part is broken", quietly demotes your email to an attachment, and hands us nothing to show. Skim now closes those dangling multiparts itself (innermost first, like a polite houseguest turning off the lights) and parses again. Your booking confirmations are back.
No more phantom attachment. That mystery .bin full of raw base64 sitting under the empty email? It was your email. It has been returned to its rightful place.
Bad parses no longer latch forever. The old code cached "I fetched this" and "there's genuinely nothing here" as the same thing, so a message that failed to parse once stayed broken until the heat death of the universe. Now Skim can tell the difference and gives previously-mangled messages one more honest attempt.
Truly empty emails say so. If a message really has nothing to render, you get a plain line saying that instead of headers floating above a void. Silence is not a UI.
Stale attachment files get cleaned up on refetch, instead of quietly squatting on your disk forever.
Everywhere
Skim v1.0.17 — "Кто-то написал вам по-немецки" 🌍
The one where a foreign-language email stops being a research project. Press T, read it. That's the whole feature.
New
Translate an email in place Skim now notices when a message isn't in your language and offers to translate it right there: subject and body, in the reading pane, where the email already was. No copy-pasting into the Ask panel, no reading your mail as a chat bubble. Hit T, or click the offer.
"Show original" is one click away because sometimes the AI's Portuguese is worse than your Portuguese, and you'd like to check.
Translations are cached the first look costs a request, every look after that is free and instant. Re-opening a thread doesn't re-bill you.
Language detection runs locally trigram tables compiled into the binary. No model files, no download, no phoning home just to figure out that "Sehr geehrte Damen und Herren" isn't English.
The AI chat learned to grow Ctrl+E expands it to fill the window, Ctrl+Shift+E throws it into a window of its own, Esc puts everything back. The little arrows finally point where they mean.
Skim v1.0.7 — "Ollama Mia!" 🎶
The one where setting up a local AI brain stops being a spelling test pick a chip, done.
And it's a special one: this is Skim's first release built on a pull request from an outside contributor.
Skim v1.0.21 — "Tick, tick, boom" ☑️💥
The one where you can finally deal with forty newsletters without clicking forty times. We know. We're as surprised as you are that it took until 1.0.21.
New
Bulk select hover a row, tick the box, and go. Shift+click grabs a range, X ticks the highlighted row, Ctrl+A takes everything loaded, Escape lets go.
Your keys already work on it. E, Del, !, V, U act on the selection when there is one, and on the highlighted row when there isn't. No new shortcuts to memorize, you're welcome.
The header quietly becomes the action bar instead of a second strip elbowing in. Same height, no rows covered, nothing new sitting there when you're not selecting anything.
Tick boxes stay invisible until they're wanted they fade in on hover, and their slot is always reserved, so nothing jumps around. Minimalism is a lifestyle.
"Select all" stops at what's actually loaded. Skim has no undo, and archiving 4,000 emails you never laid eyes on is not a feature, it's an incident.
Fixed
🚀 Skim v1.0.4 is out — "Two inboxes walk into a titlebar" 📬📬
Small update, but a big quality-of-life one: Skim now handles multiple mailboxes at once without turning into a giant multi-account control panel.
What's new:
Multiple accounts, one calm app. Connect as many mailboxes as you like. A slim switcher shows up in the titlebar only when you have more than one, with a per-inbox unread hint.
Ctrl + 1 9 to jump straight to the Nth mailbox.
Everything lands in the right place toast clicks, search hits, AI citations, cold-start opens all switch to the account that owns the message before opening it.
Search & compose stay scoped to the mailbox you're looking at no more "sent from the wrong address" moments.
No duplicate accounts try to add one that's already connected and Skim politely declines before touching your existing setup.
Skim is still what it's always been: a free, open-source AI email client for Windows, ~5 MB installer, bring-your-own-key AI. No account, no telemetry, no bloat.
Skim v1.0.14 — "Thinking, Not Loading" 🧠
The one where Skim stops insisting the model is loading while it is, in fact, sitting there thinking very hard. Turns out silence has two meanings, and we only knew one of them.
Entirely the work of @gildas-refacto in #28 thank you!
Fixed
"The model is loading " was a lie. Skim only ever watched for answer text. A reasoning model produces none while it reasons, so Skim saw silence and concluded the thing was still booting up. It now says "Thinking ", because that's what's happening.
Not just a local-model problem. Current Anthropic models reason by default, so the wrong label showed up on the default provider too. Both streaming clients report reasoning now.
The recap counter no longer freezes at "reading 20/20". It steps aside for "Thinking " the moment the mail is actually read, instead of staring at you until the answer lands.
The loading hint no longer beats the thinking one by a single frame. A flicker so brief it was almost a rumour. Gone anyway.
