Mycelium
Changelog

What changed, and why it changed.

Mycelium updates itself — it checks a static version file and offers you the new build. This is the record of what those builds contained.

0.6.0
9 Sep 2026
Current

Accounts you connect, and an update that stops breaking the app

Two of the export sources existed because there was no other way in. Gmail has an API and Telegram has an open user API, so making people request a data export for either was a worse product pretending to be a constraint. Connecting a mailbox is now one press: the browser opens Google’s own consent screen and the tab comes back naming the account. Connect as many as you like.

  • Scope is the narrowest that does the job — read your mail, and add calendar events. Not read your calendar, not send anything. Disconnecting revokes the grant at Google rather than only deleting our copy of it.
  • Mail is not a chat log. The subject carries the date more often than the body does, so it is read as part of the message. Anything with List-Unsubscribe is bulk by the sender’s own declaration and is dropped before triage. Quoted thread history is cut at the reply marker.
  • Telegram is a real login — number, code, and a two-factor password if the account has one. Message ids match the export reader’s, so having both connected cannot double up a message.
  • Tokens go to the Keychain, never to a file beside the databases. A refresh token is a standing grant to your mail and would still work if it were copied off the machine.

Three fixes, all of them things that failed quietly rather than loudly:

  • The updater installed an application macOS would not open. An .app is held together by symlinks, and unpacking with Python’s zipfile wrote each one out as a short text file naming its target. The framework broke, the signature stopped verifying, and Gatekeeper refused to launch what had just been installed. Unpacking now uses ditto, and the replacement is verified twice — once on download and again immediately before the old copy is deleted.
  • The download link had never worked. The binary is kept out of git, and the deploy dropped it, so the manifest advertised a version whose download 404’d — for every installed copy and every visitor pressing Download. Releases now build locally and deploy the built output, and nothing is announced until the exact file the manifest promises has been fetched back.
  • A stated time with no day was thrown away. “meet at 3pm” reached the queue undated and was filtered out before anyone saw it — which is the shape most real plans take, made inside a conversation where the day is obvious and never typed. A time alone now anchors to the day the message was sent.
284 tests
0.5.0
9 Sep 2026

Instagram, Messenger, WhatsApp and Telegram

Four more sources, all read from exports you can request yourself — no API key, no business account, no app review, nothing that puts an account at risk. That constraint is what makes them work for anyone rather than only for someone with a Meta app and a linked Page.

  • The honest position differs per platform, and is documented rather than glossed. Instagram and Messenger have no route to a personal inbox at all. WhatsApp has no readable local database on macOS. Telegram genuinely permits user accounts and may go live later, but that needs credentials, so the export ships first.
  • Meta writes UTF-8 escaped as Latin-1, so text either round-trips or arrives as boxes. Instagram and Messenger share a reader, with separate id namespaces so one source's decisions cannot suppress the other's.
  • WhatsApp's export is not one format. iOS brackets the timestamp and puts a narrow no-break space before AM/PM; Android uses a dash; date order follows the phone's region, inferred by finding a first field above 12.
  • Telegram's text field is sometimes a string and sometimes a list mixing strings with entity objects — reading only the string case silently dropped every message containing a link.
  • One source failing no longer hides the others. A missing Full Disk Access grant should not stop a Telegram export being read.
240 tests
0.4.0
9 Sep 2026

Conversation context, and honest times

The time column was inventing data. Only 4 of 29 real items actually stated a time; the rest fell back to 09:00, so a column of identical “9:00 AM” stamps read as precision the messages never had. A clock now appears only when the message named one.

  • Tasks were fragments torn out of a thread. The detail panel now shows the surrounding conversation, four either side, with the message in question marked. On real data this pays for itself immediately: a line that looks like a plan turns out to sit between two goodnights.
  • Group chats had no context at all — the thread's display name was stored but not its raw identifier, so context could not be fetched for exactly the threads most likely to contain a plan.
  • Clicking the selected row again deselects it.
213 tests
0.3.0
9 Sep 2026

Keyboard review, and undo

Twenty-eight items with mouse-only approve and dismiss is the single worst thing about a triage queue. J/K move, A approves, D dismisses, U undoes, R checks, esc clears.

  • The cursor advances before the list reflows, so approving lands you on the next item instead of back at the top. Getting that wrong is what makes keyboard triage feel broken.
  • Undo. Dismissals were permanent with no recovery, which is unforgiving for an action one key away. Reversing also rolls back what the decision taught the agent — without that, undoing a misclick would leave the model still believing it.
  • Empty states said “Nothing here”, which tells you nothing. Each one now names what it means and what to do next.
  • The source rows looked clickable and did nothing. A dead affordance is worse than no affordance.
212 tests
0.2.1
9 Sep 2026

A dead interface, and nine tests restored

A fix release: the interface had a section that rendered but did not respond, and nine tests removed during the previous release came back.

0.2.0
9 Sep 2026

Intents, a native window, and updates that reach people

  • Intent instead of keywords. A plan, a deadline, a payment, a reschedule — read with the surrounding conversation, and with a learning agent behind it that takes your approvals and dismissals as the training signal.
  • Auto-update. Without it every copy is frozen at whatever it was downloaded as, and two people running “Mycelium” are running meaningfully different software.
  • A calendar hand-off, still one deliberate press away from the approval.
  • A real draggable window rather than a browser tab, the monogram throughout, and the first deployed home page.
  • Plans written with a curly apostrophe were being missed entirely.
0.1.0
9 Sep 2026

Ships as Mycelium.app

A downloadable bundle rather than a script, for two reasons. macOS ships Python 3.9 and Mycelium needs 3.11+, so the interpreter has to travel with it. And Full Disk Access attaches to the application that runs the code — which as a shell script meant asking people to authorize Terminal. Confusing, and far broader than necessary. The grant now goes to Mycelium itself.

With no terminal to print to, a permission failure would be invisible, so the setup flow moved into the page: the app always starts, reports its access state, and offers a button that opens the right settings pane.

Running an older build?

Mycelium offers the update itself — or take the current one directly. 10 MB · macOS 11 Big Sur or later · Apple silicon.

Download 0.6.0