Release notes
What's new in rotli
Every release, newest first. When something works only in the Mac app or only on the web, its note says so.
[1.6.0] - 2026-09-28
Added
-
Hide what you don’t use. Settings → Appearance → Show in Rotli has a switch for each part of the title bar, sidebar and tab strip you might not want: the activity overview cards, the Browser, Theme, New and Split buttons, back and forward, the search field, All notes, Captures, Tasks, Breve, the Files, Librarian and Feedback buttons, and the tabs’ +. Nothing goes away: each switch says how to reach it without the button, and ⌘K now opens the activity dashboard, Tasks, All notes and a private browser tab. Show everything brings it all back.
-
Music in setup. First-run setup has a Sound step: stay quiet, play the studio track that matches the theme you just picked, or Claude FM (Mac). It starts playing as you choose, and the sidebar player takes it from there.
-
Ambient audio. Turn it on in Settings → General and quiet music from the Rotli studio plays from a small player above the sidebar’s footer, one track per theme (Linen, Graphite, Tide, Canopy, Dusk, Lamplight), with previous, play/pause, stop and next. Play a video in a tab and it takes over: the music pauses and waits as a toggle on the player’s left (click it to pause the video and bring the music back). Pause the video or close its tab and the music comes back. The tracks ship with the app, so nothing is downloaded. Mac app for tab playback; the tracks were composed in code at the studio (MIT).
-
Tabs that play sound show it. A browser tab playing audio wears a speaker (click it to pause), and the sidebar player controls it: previous, play/pause, stop, next (YouTube’s own buttons on YouTube), and open the tab. With Ambient audio off, the player appears only while a tab has something playing. Mac app, macOS 12 or later.
-
The player answers at once. Play, pause and stop show their result the moment you press them, ambient fades out in about a tenth of a second instead of half a second, a tab’s sound is noticed within half a second, and the chosen track is loaded before you press play.
-
Stop all sound. ⌘K → Stop all sound silences whatever the player can reach: the ambient track, Claude FM, and every browser tab. Sound from Rotli can no longer keep playing with nothing showing where it comes from.
-
Pick the ambient sound from the player. Click the title (“Ambient · Tide”) for the list: the six tracks, and Claude FM, Anthropic’s live lo-fi stream. Claude FM plays in a private browser page you never see, so it needs the internet; Open Claude FM in a tab shows it as an ordinary tab. The player always names what’s playing. Settings → General lists it too. Mac app.
-
Tuck a playing tab into the player. A browser tab playing sound can leave the tab bar and keep playing in the sidebar player. Open the tab brings it back where you are, still playing, without reloading; Close ends it. One tab at a time. Mac app.
-
The Librarian lives in the corner. Once you’ve run
/librarianin a note, a Librarian pill sits in its bottom-right corner, just left of the scroll-to-top arrow, and the conversation opens right out of it; click it again to tuck it away. After you apply its suggestions, the chat lists exactly what changed (“Tagged: …”, “Filed in …”), and a line under the box says what it’s for: it only organizes; for anything else, Open in Chat. Mac app. -
Tell the Librarian how things are. In
/librarian, say something like “Ana and Leo are work people; so was Sam, but not anymore”. The Librarian adds a filing rule, makes a note for each person you haven’t written about yet (their name and what you said, filed in People › Work), and asks you before changing anyone who already has a note, with Yes and No, and then only their tags and folder, never their words. Every new note shows in Librarian Activity with Undo. Mac app. -
A badge when the Librarian asks. Whenever the Librarian has a question for you, its button in the sidebar shows how many; click it to go back to the conversation.
-
Your rules for the Librarian. Settings → Librarian → Your rules tells the Librarian how you want things kept, in plain settings:
- Secure keywords: a note whose title or file name has one of these words (bank, passport, tax return…) becomes secure when it’s saved and moves into your protected Secure folder. Only the name is checked, never what the note says, and never by a model; “bank” matches “Bank login”, not “Riverbank”. Secure matching notes now protects notes already named that way.
- People: split into Family, Friends, Work and Acquaintances (rename, remove or add your own), or keep one People list. A person is filed into People › Friends and so on; a group’s folder is made when its first note is filed.
- Filing rules: plain sentences (“Recipes go to Cooking”) the Librarian
follows when it files a note on its own and when you ask it with
/librarian.
The rules are kept with the vault’s settings on this Mac. Mac app.
-
The Librarian, as a chat. After your first ask, the Librarian pops out into the bottom-right corner of the pane you’re in, like the chat on a website, and the format bar comes back. Keep talking with the model you picked. It is still the Librarian, not a second Chat: it organizes this note (tags, marked passages, filing), asks what you mean when it needs to, and lists what it would change for you to tick and apply, right in the conversation. Ask it for anything else (an answer, a draft, research) and it says so in one line and offers Take this to Chat, which opens a new chat about the note with your question already typed; Open in Chat is always in its header. Quick asks (“Suggest tags”, “File this note”, “Mark the highlighted passage”) sit above the box. Each question carries the passage you had highlighted. The Librarian’s corner button shows only once you’ve run
/librarianin that note, so notes you haven’t asked about stay clear. The model picker is now the searchable one from Chat, grouped by provider. The passage you highlight stays highlighted while you type to the Librarian (it used to vanish as soon as you clicked into the bar). Escape or − tucks the chat into a button in the same corner; × ends the conversation. The conversation lasts while the app is open and is never saved to your vault. Mac app. -
Talk to the Librarian from a note. Type
/librarianand the format bar becomes a small Librarian bar: pick a model, highlight a passage if you like, and ask (“tag this”, “mark this passage”, “file it with People”). The Librarian proposes; nothing changes until you tick what you want and press Apply. It can tag the note, mark a passage (a pointer saved in the note’s metadata that finds the words again; the note’s text is never edited), and file the note into a Library area, creating People if you don’t have it yet. Every change shows in Librarian Activity with Undo, and the bar lists the note’s marked passages so you can jump back to them. Locked and secure notes, notes outside the Library, and text that looks like a secret are refused before anything is sent. Escape brings the format bar back. Mac app. -
Clean up leftover note names. Older notes could carry names they never really had in their metadata: “Untitled”, “untitled (7)”, or a title caught half-typed (“Round”, “Round Three -”). Settings → General → Leftover note names counts them across your vault and removes them in one click. A name that a link still uses is kept, so no link breaks. Mac app.
-
Three more moods for your quokka. Settings → Appearance → Idle mood now has Friendly (waving), Inquisitive (looking into things), and Adventurous (off exploring) beside the original five, each wearing your accessory.
-
A thank-you at the end of setup. Before the guided tour, a small card thanks you and shows a banner made from your choices: your quokka (its color and what it’s wearing) on your theme, with your name if you gave one. Star Rotli on GitHub, copy an invite for a friend, share on X, or save the banner to your vault’s Assets. Share on X opens a post with a standard caption and a link to rotli.co and puts your banner on the clipboard to paste in; nothing about you goes into the link. Closing the card starts the tour.
-
What’s new, after an update. The first launch after an update opens a small card with the release’s top changes — once, and never on a fresh install. A change that is only in the Mac app or only on Rotli Web says so. “See everything new” opens the full changelog, now on rotli.co (linked from the site’s footer), and the palette’s “What’s new in Rotli” brings the card back any time.
-
Feedback in the sidebar. The sidebar’s footer gains a Feedback button beside Files, Librarian, and Settings; it opens the same prefilled GitHub issue as Settings → About. When the sidebar is too narrow for the labels, the footer shows its icons alone instead of cutting the names short, and the Librarian’s count and the update dot sit on their icons, so a label is never squeezed.
-
Boards match your theme. A board you haven’t colored yourself is your theme’s own color, in all fourteen environments, and changes the moment you change themes. A color you pick on a board stays that board’s (plain white counts as no color). Settings → Appearance → Board background → White keeps boards and their tools light, like paper, instead. Only a color you chose is saved into the board file. A board inside a note matches too.
-
Chat replies show images and video from your vault. When a reply links an image or a video in your vault on a line of its own, the chat shows the picture, or a video you can play, instead of the link’s text. Only files in your vault are shown; an image at a web address is never loaded. On Rotli Web a video shows its name instead of a player.
-
A video a chat made shows as a video in the chat’s list of files, with its own mark and “Video · MP4”, instead of as an unnamed file.
-
Hand to AI. Choose “Hand to AI…” from the palette or a note’s menu and Rotli turns the note into a prompt for Claude Code or another agent: the goal, the open tasks (and what’s already done), the note as context, and what “done” means. Edit it, then copy it. It is built from the note alone; no model runs. A secure note, or one that looks like it holds a secret, is never turned into a prompt, and the window says why. Type
/hand to AIin a note for the same window, or search ⌘K for “send to AI”.
Fixed
-
The Librarian checks again before every message. Its chat decided once, when it opened, whether it could read the note; a note made secure, locked, or given a secure keyword in its name mid-conversation could still be sent. It now asks before each message, and nothing sends until that answer is in.
-
Hand to AI respects secure keywords. A note named with one of your secure keywords is refused a prompt right away, as the Librarian refuses it, even before a save has marked it secure.
-
A secure note’s name stays out of Rotli’s logs. When making a note secure by its name failed, the log line named the note’s path; it now says only what failed.
-
Escape closes the Librarian from the note too. With the caret back in the note, Escape used to hide the window instead; it now closes the Librarian bar or tucks its chat away first.
-
The Librarian never marks the wrong passage. Asked to mark words that appear more than once in the note, with nothing highlighted, it used to pin the first; it now leaves the mark out rather than guess.
-
A tab tucked into the player stops with the window. If the window reloaded while a tab was tucked into the player, its page kept playing with nothing to stop it; the next start now closes it.
-
Rotli Web: ambient music plays. The tracks were asked for at the wrong address on the web, so the player stayed silent.
-
Rotli Web: the search button can’t be hidden. On the web it is the only way into the palette, so Show in Rotli no longer offers to hide it (or the Browser button, which the web doesn’t have).
/librarianis left out of the web’s slash menu, and What’s new marks the Mac-only items. -
/librarianis ready to type in. Choosing/librarianputs the cursor in its box right away, so you can start typing without clicking it first. -
Bold over a selection that spans lines. Selecting a whole line and pressing Bold used to leave it plain and put
****in front of the next line, breaking its bullet. Bold, italic, and the other marks now format each selected line’s text and leave list, task, heading, and quote markers alone; if every selected line is already bold, Bold takes it off all of them. Selecting text that is only partly bold (a bold word and the plain words after it) and pressing Bold now makes it one bold span instead of adding stray stars; selecting part of a bold span unbolds just that part. Strike, highlight, and underline work the same way. -
A file dropped from Finder onto an open board no longer lands in another note. Boards don’t take dropped files yet, so the file is saved to Assets and a notice says so. Mac app.
-
Boards use your accent color. The selected tool and active controls were still Excalidraw’s own violet in both light and dark.
-
A remote-agent relay on
http://[::1]is accepted for development, like127.0.0.1andlocalhostalready were: an IPv6 host arrives in brackets, so the loopback check never matched it. -
A new web vault’s Tasks page and This week card are right at once. The Tasks page read “Nothing open” and the sidebar’s This week card “0 new” until a reload, though the Welcome lessons had just arrived with thirty open tasks.
-
Rotli Web says what the web can do. A note’s header says “In your folder”, not “On this Mac”, and the new-tab chooser shows the private Browser as “In the Mac app” instead of offering a tab that could only fail.
-
Settings tells a screen reader which pane is open.
-
Big images save on a board. An image over about 75 KB made a board refuse to save, because an image is kept inside the board as one long string and every string had a 100,000-character cap. An image’s data is now exempt from that cap; every other string keeps it, and a whole board is still limited to 8 MB.
-
A
[[link]]to a board opens the board. It used to open the board as a note. -
Find in this file shows what it matched. Every match is marked on the page and the current one stands out, the way find works everywhere else. Before, the match was selected but did not show while you typed in the find box.
-
Moving a note to Trash closes its tab, in every pane, the way trashing a file already did. A trashed board’s tab closes too.
-
“Untitled” no longer ends up in a note’s metadata. A new note’s placeholder name and each half-typed title (“Round”, “Round Three -”) were saved as aliases while you typed. Now only a real rename keeps the old name, so links to it still work, and a rename clears old “Untitled” entries.
Changed
- A rotli.co link now shows the island. The link preview in iMessage, Slack, X, and Discord keeps its headline and app window, and adds the film’s Rottnest: the lighthouse on its hill, the bay, and the quokka waving from the sand.
- rotli.co’s 404 page is a sunset. A missing page now fills the window with the film’s sunset and the waving quokka, with one button home and no header or footer.
[1.5.0] - 2026-09-24
Added
- Blossom, a seventh theme family. Light pink by day and a deep plum-rose at night, tuned like Iris: soft, never candy, and every text role clears AA contrast. Choose it in Settings → Appearance or cycle to it with the titlebar sun, between Iris and Midnight.
Changed
- rotli.co now tells the story the way the film does. The landing page opens with the 60-second quokka film, playing muted with “Click for sound”, and walks through what rotli does in three steps: write, keep, ask. The privacy band is a night scene, the questions have room to breathe, and the page closes on the film’s sunset. The eight “Rotli in 30 seconds” episodes live in one player at the top of Features, and About and Privacy open with scenes from the island. Motion plays once and rests, and reduced motion shows everything at rest.
- ⌘⇧A opens the Aa panel (text size, measure, view, blocks, and Secure) for the note you are in, in the main window and the Quick Note; press it again to close. Archive no longer has a default shortcut. It is still in ⌘K, and you can give it one in Settings → Keybindings.
- ⌘⇧C works in the Quick Note. It opens the note’s chat where your chats live: in the main window, brought forward, or in the Chat window when you have popped Chat out. It is the same chat ⌘⇧C opens from the main window.
[1.4.2] - 2026-09-23
Added
- Jump through the Quick Note’s note list by number. With the list open (⌘P), ⌘1–⌘9 opens rows 1–9 and ⌘⇧1–⌘⇧9 opens rows 10–18; hold ⌘ to see each row’s number. All of them can be changed in Settings → Keybindings.
Fixed
- ⌘⇧L works in the Quick Note. It marks the open note secure (or not), the same as in the main window, and the shield in the Quick Note follows it.
- The scroll-to-top arrow no longer overlaps the format bar in a narrow window or Quick Note; it moves up above the bar when they would meet.
[1.4.1] - 2026-09-23
Fixed
- Your vault can stay open in Obsidian and ZenNotes too. ZenNotes moves
files it does not recognize at a folder’s top level into
assets/, and it took the file that marks the folder as a Rotli vault. Rotli then opened your vault as a plain folder, added empty Board, Inbox, Vault, and Secure notes folders to it, and refused to connect it. Rotli now moves those files back when it opens the vault, keeps a hidden backup of the marker, and adds an empty.obsidianfolder, which ZenNotes treats as another app’s vault and leaves alone. - Connect vault takes any folder. An Obsidian or plain Markdown folder now opens in place instead of failing with “Choose an existing Rotli vault or an empty folder”, and the vault menu always lists the folder you have open.
- ⌥Q opens only the Quick Note. With Stay open on and the main window (or the Chat window) left behind another app, the Quick Note brought it up too. Those windows now step aside while the note is up and return, behind whatever you are using, when you close it or click away.
- No more “Untitled” in the Quick Note. Its note list leaves out blank notes, a blank open note is titled New note, and ⌘N reuses a blank note instead of making another.
Added
- Hold ⌘ in the Quick Note to see its shortcuts, like the main window: badges on its buttons, or the shortcut panel, per Settings → Keybindings.
- Holding ⌘ right after typing now shows the shortcuts at once; before, you had to tap ⌘ once first.
Changed
- The Rotli Helper installers now download Rotli Helper 1.4.0, which tells Rotli Web which models your AI tools offer, so the web chat lists them live.
- A new rotli.co. A simple first screen: the promise, one sentence, and the two ways in over a faint pattern of note and folder icons, with the waving quokka peeking over the product just below the fold (no autoplaying film). Each feature sits beside a real still or a plain drawing: the Markdown a note is saved as next to how it looks, chat, how the Librarian files notes, and a table of what each kind of AI may do with everyday, secure, and locked notes. New chapters for the ways in (Mac, Rotli Web, Rotli Helper) and common questions; plain-language copy in place of internal terms; a pinned header with Features, Privacy, and Download; a footer with link columns. Download is now a chooser with one clear button per option. Theme and companion previews change only when you pick one (nothing cycles on a timer), the companion steps with full-size buttons, and the film plays on request. The menu now leads to real pages: a new Features page with the whole tour, and a new Privacy page that explains, in plain language, what rotli does with your data, what connects to the internet and when, and why it works that way. The header has one Download button, which opens a download page that leads with your own system (Mac now; Windows and Linux coming soon, with Rotli Web in the meantime). Resources and the other pages line up with the rest of the site, with an “On this page” list on longer articles. The Features page is organized the way you meet rotli, with crisp captures of the real app: one note shown rendered and as the Markdown it is saved as, every kind of block, how chat keeps running notes and can write for you (and how Lock stops it), Word documents, boards, and sheets (coming soon), where assets are kept, and how rotli connects to the AI tools you install yourself in Terminal, with Rotli Helper doing the same for Rotli Web. Fixed: the film section’s stale length and wording, the film poster that still said “Mac beta in preparation”, a missing space before “The story behind the name”, and site copy that still described a browser-storage mode Rotli Web no longer has (every note now lives in a folder on your computer).
- Launch film sources left the repository. The film project (the
HyperFrames edit, review notes, and render scripts under
marketing/) is media work and now stays local to the maintainer;/marketing/is ignored. The published film insite/public/media/is unchanged. The unused hero teaser clip was removed with the old landing page.
[1.4.0] - 2026-09-23
Added
- The public site footer now also includes a Featured on Founder.best badge, beside the Launch Llama one.
- Boards on Rotli Web. ⌘N → Board (or ⌘⇧T) makes a named Excalidraw
board as a real
.excalidrawfile in your vault folder — the same file, in the same place, Rotli for Mac makes — and your strokes save into it. Boards are listed in Main and All notes, open after a reload, and move to Archive or Trash and back like notes. The canvas’s fonts ship with the app, so drawing and writing on a board never reaches the internet. Reveal in Finder stays a Mac-only action. - Chat offers every model your CLI does. The model picker, Settings, and
setup now ask Claude Code, Codex, Cursor, and Antigravity which models they
offer and list exactly those — Claude’s Default (Opus 5.5 with 1M context),
Opus, Fable 5.1, Sonnet 5, and Haiku 4.5; Codex’s GPT-6 Astra, Sol, and Luna;
Cursor’s full list — so a new model shows up without an update to Rotli.
Reasoning effort and Fast follow what each client says the model supports.
Nothing is sent to a model to find out. Chats saved on a bare
opusorfableopen on the matching model. Rotli Web gets the same lists once Rotli Helper is updated; an older helper keeps the built-in list.
Changed
- Documents stay on the Mac for now. On Rotli Web the ⌘N chooser shows Document as coming soon, and no menu, command, or chat tool creates one there; Rotli for Mac is unchanged.
- Rotli Web needs a vault, and sets one up first. Nothing opens until a vault folder on your computer is connected, so a note can only ever be a real file there. Chrome, Edge, and Arc pick the folder directly; Zen, Firefox, and Brave use Rotli Helper, which now saves your notes into the folder you choose instead of keeping a copy in the browser. An empty folder becomes a new vault with the Welcome lessons; an existing vault opens as it is. Safari and phones are told plainly that they can’t connect a vault yet.
- Rotli Helper starts when you log in, and pairing is one press. The
install line registers it as a login item and opens Rotli Web with the
pairing code already filled in: press Pair, see that it worked, and
Continue to choose your vault.
--uninstallremoves it. It serves only the one folder you pick with your computer’s own folder picker, and the installers now download Rotli Helper 1.3.0, the version that can serve it. - Nothing leaves your computer. Rotli Web may talk only to Rotli Helper on this computer; a new check fails the build if that ever widens, and a test proves the app never asks. Notes kept inside the browser by an earlier version are offered for copying into your vault.
Fixed
- The sidebar shows where you are after following a link. A note Main doesn’t hold now highlights the row it lives under — Captures, Library, Assets, Archive, or Trash — instead of leaving nothing (or the note you left) highlighted.
- Rotli Web leaves the browser’s shortcuts to the browser. App hotkeys (tabs, history, panes, views, the two-step leaders) no longer fire on the web, where ⌃Tab, ⌘[, ⌘← and friends belong to the browser; bold, italic, and the other formatting keys still work, and no hint names a key that does nothing. Settings has no Keybindings pane on the web.
- The caret sits beside an empty task’s box. After typing
[]the caret floated above and to the right of the new checkbox (most visibly in Zen and Firefox); it now sits level with the box, where your text will start. - The caret sits on the “Write…” line of an empty note instead of above it (Zen and Firefox).
- A link to one of two same-titled notes opens it. When titles collide the link picker writes the note’s path, and on Rotli Web that link read “No note with this name”; it now opens the note it names.
- “Notes kept in this browser” asks once. Rotli Web offers to copy notes an older version kept inside the browser into your vault. Not now is now remembered (Settings → General offers it again), and notes already copied on an earlier visit are cleared from the browser without asking.
- New notes can be created on Rotli Web. ⌘N and the tab strip’s + said
“Couldn’t create”; a new note is now a file in your vault’s
wiki/_inbox(orwiki/with the Librarian off), exactly where Rotli for Mac puts it. - Dragging a block by its handle moves it whole. A block dragged down landed inside the text below it, splitting a word; it now lands where the drop line shows. Dropping below the last line moves it to the end of the note, and a move no longer leaves blank lines behind.
- Pairing waits while the browser asks. Zen and Firefox ask before a page may connect to apps on your computer; pairing gave up before you could answer and said nothing was running. It now waits, and says to choose Allow. Setup also follows the helper’s latest answer, so after Allow it moves on to choosing your vault instead of still saying the helper isn’t answering.
- Connecting a vault on Rotli Web no longer bounces you back. In Zen, Firefox, and Safari an empty folder looked exactly like a cancelled picker and nothing happened.
- A lost connection never lands notes somewhere else. A vault that can’t be reached at startup shows a reconnect screen naming it, instead of quietly opening an older copy in the browser; a helper that stops answering holds your edits until it is back.
- A hard refresh right after typing keeps what you typed.
- Welcome lessons in a connected folder are ordinary notes, not Captures, in Rotli Web and in Rotli for Mac.
[1.3.0] - 2026-09-21
Added
- Slash commands work inside a list item, after your text. Type
- [ ] Ask Gabriel /linkand the menu opens right there — no need to drop to a new line. Link note, Link chat, and Inline code go into the sentence; any other command lands just beneath the item. Ordinary slashes in your writing (and/or, a web address,yes / no) never open it. - Link a chat, not just a note. The new Link chat command lists your chats and inserts a link; clicking it opens that conversation. Hovering shows the top of the chat, like any linked note.
- Templates. Keep your reusable layouts as ordinary notes in a folder named
Templates, then type
/templatein any note, pick one, and its content drops in where you were typing. In an empty note the template’s heading becomes the note’s title; in a note you have already started, only the content below that heading is added, so your note keeps its own name. The Librarian leaves the Templates folder alone. The picker’s Create new makes a new template right there and opens it. Rotli also offers a few built-in starters — meeting notes, a daily note, a project brief, a bug report, a weekly review — after your own; they are never saved into your vault, one of yours with the same name takes its place, and Settings → General → “Offer built-in templates” turns them off. Works in the Mac app and in Rotli Web. - Settings → Chat. One place for how chats start: the model every new chat opens on (with a button that sends it a real test message), whether a new chat asks for a name first, and whether it is renamed by what it is about. The naming choices moved here from General and Appearance.
- Chat in its own window. Drag the Chat switch out of the sidebar — or use its small corner button, or right-click it — and Chat opens in a window of its own that holds only chats; ⌘T and ⌘N there start a new chat, and the sidebar button up top (or ⌘0) hides and shows its chat list. While Chat is out, the main window’s switch shows only Home (and Breve), with a button at its end that brings Chat back; the Chat window has the same “Put Chat back in the main window” button at the top of its list. Chat cannot be pulled out while a chat is still answering. Mac app only.
- Change views from Chat. The Chat side now shows which view you are in and lets you switch — Main for every chat, or one of your views — without going back to Home. A note made with ⌘T or ⌘N while a view is active lands in that view and in Main, wherever you press it. A view lists only the chats in it — a view with none shows none, instead of falling back to every chat — and Main still lists them all.
- Rotli tells you when there is an update. It checks its release page shortly after it opens and a few times a day, and marks the Settings button — in the title bar and at the bottom of the sidebar — with a small dot when a newer version is out. Nothing downloads until you choose Install & relaunch. Settings → General → “Check for updates automatically” turns the routine check off; the Check for updates button stays either way.
- Two-step hotkeys: ⌘⇧W for views, ⌘⇧S for your top notes. Press ⌘⇧W and the view menu opens with ⌘1–⌘9 beside its choices; press the number to switch. Press ⌘⇧S and the first nine notes at the top of Main show their numbers; press one to open it. Pin or drag a note to keep it in its slot. ⌘1–9 still jump between tabs the rest of the time, Esc backs out, and both hotkeys can be changed in Settings → Hotkeys. Works in Rotli Web too.
- New chats are named by what they are about. A chat still gets its name the moment you send — then, after the first reply, the model you are chatting with suggests a short name that says what the chat is for, and the name updates. It is one small extra request to that same model and no other; a chat that touched a secure note is never sent to a remote model for this; a name you typed is never replaced; and the chat’s file never moves. Settings → Chat → “Name new chats by what they are about” turns it off. In Rotli Web without the Helper, chats keep their first-words name.
- Hover a
[[link]]to see the top of that note. Rest the pointer on a link and a small card shows the note’s title and first lines without opening it; a click still opens it. A secure note’s card shows its name and none of its text. Works in the Mac app and in Rotli Web. - Send feedback. Settings → About Rotli (and ⌘K → “Send feedback”) opens a new GitHub issue that starts with your Rotli version and operating system, and nothing else.
Changed
- The Chat switch no longer shows a number. The count of chats would not hold up at a thousand, and screen readers read the button as “Chat 3”; it is just “Chat” now.
- The sidebar’s right-click menu always offers the other choice. It used to list “Keep sidebar open” and “Open sidebar on hover” together, and picking the one already in use did nothing. It now shows only the one you are not using, so a click always changes something.
Fixed
- “Couldn’t save Main — revision conflict” is gone, and so is the lock-up behind it. When the CLI, the Librarian, or a views change saved Main while the app held an older copy, the app showed a raw revision error — and then every later change to Main failed the same way until a restart. Rotli now re-reads Main, keeps your rearrangement together with whatever was added or removed meanwhile, and saves again without a word. If Main was rearranged in both places at once, you see the saved version and one plain sentence asking you to make the change again. Named views recover the same way, in the Mac app and in Rotli Web.
- A folder name with
/or:is refused when you type it. Main used to accept the name and a view refused it later with “invalid folder name in view”. The rule is now the same everywhere, in plain words, and a folder that already has such a name moves into a view with the character replaced by a space. - Dragged rows land where you aim. The label that follows the pointer hung below it, so its middle sat most of a row under the real drop point and a row aimed with the label landed one place too high. The label now rides beside the pointer, centred on the drop line, and the drop is checked once more at the moment you let go. This applies to every drag: Main, tabs, board cards, and chats.
- A chat that starts with an image is no longer named “[Image #1] …”. Image tags are left out of the chat’s name, its file name, and its Main folder; a first message with only images is called “New chat”.
[1.2.0] - 2026-09-18
Rotli 1.2: Add to folder for a whole selection, Tasks rebuilt (and working in Rotli Web), Captures tidied, a hover sidebar that pushes instead of covering, spelling underlines in the Mac app, a Secure switch with ⌘⇧L, a helper that says what went wrong instead of “network error”, and a larger rotli.co (Resources, Blog, About, Download, and a new link preview).
Added
-
rotli.co: Resources, Blog, and About. The header now lists Product, Resources, Blog, and About, with Open in browser and Download beside them on every page, and folds into a Menu on narrow windows and phones. Resources answers questions in short articles (“Why local?”, “rotli in the browser and on the Mac”); About tells where the name comes from — rotli is short for Rottnest, the island where quokkas live. Blog posts can sit as drafts on the dev site until they are ready. The MCP guide moved to
/resources/mcp/(still dev-only);/mcp/redirects. -
rotli.co: more to read, and a download page. Three new resources — “Getting started”, “What does AI see in rotli?” (secure and locked, explained), and “What is Rotli Helper?” with the install line for each system — and
/download/, which lists the Mac app, Rotli Web for Windows and Linux, and the helper in one place. -
⌘⇧L turns Secure on and off for the open note, and the Aa panel has the switch. One key keeps a note away from remote AI, and the same key lifts it again. It appears in ⌘K and can be rebound like every other shortcut. The Aa panel gains a Secure · this note row (Off / Secure) that shows the current state and the shortcut beside its label. Mac app only.
-
Add to folder, for one note or a whole selection. Select several notes, right-click, and choose Add to folder: pick one of your Main folders, or New folder…, which files them and opens the folder’s name for you to type. They land in the order Main lists them. Works from the sidebar and the Library browser, on the Mac and the web.
-
Tasks works in Rotli Web. The list was always empty in the browser; it now shows every open checkbox there too, and checking one off edits the note, exactly as on the Mac.
-
Click a task to land on it. A task’s words in Tasks open its note with the cursor on that task, even if the note changed since. The note’s title still opens it at the top.
-
You choose when tasks are archived. Settings → General → Tasks: two weeks, 30, 60, or 90 days, or Never. Thirty days is the default.
-
Archived tasks. Tasks in notes you haven’t touched for 30 days rest in a closed Archived section with a count. Nothing moves; edit the note and they come back.
Changed
-
Captures, tidied. A search field narrows the cards, Select all sits with the header’s tools instead of beside the title, the select mark is the app’s checkbox (not a circle) and stays out of the way until you point at a card or start selecting, Clear sits beside the count on the same line as the actions, and cards show words rather than
[[link]]syntax. Right-click a selection to Add to folder. -
Tasks is easier to read. Each note is a clear group: its title as a header, its tasks hanging under it on a rule, and a chevron to fold it away. Long tasks wrap instead of being cut off, the search field is a proper one (no more doubled magnifier) and narrows to the tasks that match, and the explanation line waits behind a ?.
-
rotli.co: Download and the browser, side by side. The hero offers Open in your browser and Download for Mac; on Windows, Linux, and phones the browser comes first. The Rotli Web section moved up under the hero, with a real capture of the web app and copy that matches 1.1 (open a real folder in Chrome, Edge, or Arc; chat through Rotli Helper).
-
rotli.co: the vault drawn on the page. “One folder. Every path out stays open.” shows its example folder larger and straight on the page, without a card.
-
A new link preview. Shared rotli.co links show one line, the app tilted in from the right, and the quokka waving up from the bottom edge over a faint pattern of file icons. The wordmark now renders in Baloo 2 as it always meant to.
Fixed
- Spellcheck leaves code and links alone. Inline code, link targets, and code blocks are no longer spell-checked, so red underlines stay on your own words. (Underlines that come and go on ordinary text are still being looked into; the Mac draws those itself.)
- Spelling underlines in the Mac app. Misspelled words were underlined in Rotli Web but not in the Mac app: macOS only checks spelling as you type in an embedded web view when the app asks it to, and rotli never had. It does now, unless you have turned “Check Spelling While Typing” off yourself.
- Nothing in a note starts left of its text edge. Bullets sat a few pixels outside it and always had; they, numbers, and checkboxes now start on the edge or inside it.
- Numbered lists line up, whatever they count to. Numbers start on the text edge, and a list that reaches ten gives every item the same column, so “1.” and “10.” start together and so does their text. A list that stays under ten looks as it always has.
- Right-click menus open away from the window’s edge. With the sidebar on the right the menu was pushed along the edge and landed on top of the row you clicked; it now opens to the left of the pointer (and upward near the bottom), like every Mac menu.
- The highlight in Main starts beside the note’s icon. Hover, the open note, and a gathered selection no longer paint all the way to the sidebar’s edge, so notes inside folders still read as nested. The whole line is still clickable.
- Dragging a selection moves all of it. Click a note, then ⌘-click two more, and the first one now counts as selected too (as in Finder); before, dragging by it moved it alone. A selection dragged out of the Library browser into Main now lands whole as well, and dropped notes keep their order.
- The sidebar on hover pushes your note over instead of covering it. Opened from the window’s edge it is now the same sidebar ⌘0 shows: the content moves aside, nothing sits on top of the note, and the edge can be dragged to resize it — the width is remembered. Resizing, or dragging a note out of the sidebar, holds it open until you let go. On the Mac and the web alike. And ⌘0 pressed just after the pointer leaves the edge no longer has the sidebar shut itself a moment later.
- The window can no longer slide sideways. Jumping to a find match could push the whole frame left, cutting the sidebar off, with no way to scroll it back. The frame now clips instead of scrolling.
- Rotli Helper: a refused chat request no longer looks like a network error. When the helper turned a request away (a stale pairing code, for one) it answered before it had read what the page sent, so the connection was cut, the page reported “network error”, and the helper’s window filled with “Broken pipe”. It now reads the request first, so the page shows the helper’s real words — “pair again” when the code is stale — and a page that simply left is no longer logged as an error. The Mac app’s local agent server had the same flaw and the same fix. Ships in helper 1.2.0; run the installer line again to get it.
[1.1.0] - 2026-09-17
Rotli 1.1: Rotli Web (a vault in the browser, a copy where the browser can’t write, the Helper for chat), chats that carry their model, native drops fixed, the prompt navigator as a stack of cards, a sidebar that sits on either edge or opens on hover, and a day of the owner’s fixes.
Added
-
The sidebar sits where you want it, and stays only if you want it to. Appearance → Sidebar: Left or Right, and Always or On hover. On hover keeps the sidebar out of the way until the pointer reaches the window’s edge, then slides it over the content and away again when the pointer leaves (Esc too); ⌘0 still brings it. Right-click the sidebar’s own surface for the same choices. Remembered on the Mac and on the web alike; the defaults are left and always.
-
Rotli Web: Files opens Finder through the Mac app. The page hands the file you’re in to the installed app by its
rotli://reveallink, and the app opens Finder at it — for the note or the chat that is open. The app answers only for its own vault. With nothing on disk behind the note, the vault’s own browser opens at its folder as before. -
⌘← and ⌘→ go back and forward beside ⌘[ and ⌘], never inside a text field (where ⌘← is line start). Remappable like every chord.
-
rotli.co has a proper 404. The site’s missing-page screen wears the mark, says what is at
/appor/helperbefore they are switched on, and offers the ways back: home, the download, Rotli Web, the roadmap. -
Rotli Web says when a copy has aged. A connected copy of a vault is a snapshot; it never follows the folder. Once a copy is half a day old the sidebar says so in one muted line — “Copy of X taken 2d ago. Reconnect” — and Reconnect vault always sits in the vault menu. A fresh copy says nothing.
-
The open chat shows its file’s model. A chat this device never pinned seeds its model from the
model:line in its file, on the web and the Mac alike, so a copy of the vault opens each chat on the lane it ran on. -
Rotli Web: Files reveals the open chat too. With a chat open, Files opens the vault’s browser at the Chats folder that holds its file.
-
The prompt navigator is a stack of cards. Hovering the left-edge markers now shows the prompt you’re on as its own card with up to three neighbours above and below, each a step further tinted into the pane (never see-through), instead of one tall list that a long thread outgrew. Hover a marker to move the stack; click a card to jump.
-
A chat opens as its file from the Library and from Show source. A chat row in the Library opens the transcript as a Markdown note in the editor, editable; the source peek’s Open does the same. The Chat front is where the same file opens as a chat.
-
Every chat carries its lane. The one-time backfill now completes a chat that has a model but no provider (a model the old picker stored by label, “Gemini 3.5 Flash (Medium)”, is Google’s Antigravity lane) and stamps a chat this device never pinned with the vault’s default model — the mark the app already showed for it.
-
Rotli Web: Files is a shortcut to where you are. The footer button opens the vault’s files at the folder of the note you’re in (the Mac opens Finder); the Library root only when nothing is open.
-
Rotli Web (first phase). The app now builds for the browser (
bun run build:web) and the site serves it fromrotli.fun/app/when theWEB_APP_ENABLEDknob is on. No account: the vault lives in the browser’s own storage on that device, and the page’s Content-Security-Policy isconnect-src 'none', so the browser refuses every outbound request. Notes, folders, Main and named views, settings, and the open tabs persist across reloads; a first visit seeds and opens the Welcome folder. Chat and every model lane, the Librarian, Breve, agents, sheets, Word files, and Finder drops stay in the Mac app; the web build withholds them by platform. Chat stays visible, disabled, and says on hover that it is in the Mac app (a click opens the download); Settings → General says where the notes live. Its top bar is a toolbar, not window chrome: the brand sits where the Mac app keeps its traffic lights and links back to the site, and there is no window drag or private browser. In Chrome, Edge, or Arc, Open a folder on this computer (sidebar → Connect vault, or Settings → General) makes a real folder the vault: every note is a file there, the same files the Mac app reads, and the browser remembers only the folder. Firefox, Zen, Safari, and Brave (until its folder flag is on) cannot write to a folder; there Import a folder keeps a copy in the browser and Export vault (.zip) gives it back. Boards are the next phase (docs/design/web-version-and-shell-batch-2026-09-16.md). -
Rotli Helper: chat on the web. A small program you run on your own computer (
rotli-helper, Mac, Windows, and Linux; not the Mac app) lets Rotli Web chat through the AI tools installed there — Claude Code, Codex, Cursor — with your notes as context. Start it, paste the pairing code it prints into Chat → Connect, and Chat is a real front: the tools’ guides then know what is installed, and a message goes to the tool you pick and its reply comes back. The helper listens only on your own computer, only for pages from rotli.co, and only for a paired page; images are not sent through it in this release, and a note in a secure folder or carrying a secret never reaches a model. One line in a terminal installs and starts it:curl -fsSL https://rotli.fun/helper/install.sh | shon Mac and Linux,irm https://rotli.fun/helper/install.ps1 | iexon Windows; the dialog shows the line for your computer, with a copy button, and once paired it checks which AI tools are already installed and signed in and says Connected. Safari cannot reach the helper; every other desktop browser can (some ask once for local network access). Web chats are saved in the browser vault. -
Rotli Web: images in notes. Drop an image onto a note in the browser and it is kept the way the Mac app keeps it: as a file under the vault’s
storage/images/(orStorage/in a plain folder) when a folder is connected or imported, and inside the browser vault otherwise. The note gets the samestorage:link the app writes, so the same note and image open in both, and the image shows from the stored bytes and is still there after a reload. The web keeps the app’s guards on the way in: only a real raster image (the bytes must match the name), never empty, at most 25 MB. A drop on a web chat says files cannot go through Rotli Helper yet and to drop images into a note instead; a non-image dropped on a note says the web takes images only. Either way the page stays put. -
Guided setup for the connected models. A lane that is not ready walks you through it instead of hiding a hint: Settings → AI Models shows the steps open (install with the tool’s own command for your OS, copy button beside it; sign in, in your terminal; come back — Check again asks right now), and steps Rotli can already see done are ticked. The chat’s empty state shows the same steps when no model can answer, with a door to Settings. On Rotli Web, Chat and the note’s chat chip stay visible and a click opens Chat on the web: install Rotli Helper (a small program for Mac, Windows, and Linux, not the Mac app; marked plainly as not released yet), connect the page to it, and set up the AI tool now.
-
Chat: while you drag an image over a chat, its composer rings and a label says what the drop will do — “Drop to attach”, or that the current model can’t see images. On Rotli Web the label says images can’t reach Rotli Helper yet and points you to a note, and a note now draws the same drop line the Mac app shows while an image hovers it.
-
Sidebar: drag an image onto a chat in the sidebar and the chat opens with the image attached; drag it onto a note in Main and, after a short hold, the note springs open so you can drop into it — or drop on the row and the image lands at the note’s end. The row you are over lights up. On Rotli Web a note row works the same; a chat row says the Helper carries text only.
-
Chats carry their model in the file. Each chat’s
chats/<slug>.mdnow recordsmodel:andprovider:in its frontmatter — written when you pick a model for the chat and when a chat is first saved — so every copy of the vault, on the web or another Mac, shows the right mark. Chats from before get the lines once, on the next launch, from the per-chat models this Mac already kept in its settings. -
Rotli Web: the vault switcher names the vault you connected (the folder’s own name) instead of “Rotli”.
-
Rotli Web: browsers that can only read a folder still connect a vault (as a copy kept in the browser) — the dialog and Settings say so, and explain that the browser’s “upload” is its word for letting the page read the files; nothing is uploaded anywhere.
-
Chats: Show source in a chat’s menu shows the transcript file as written (both twins), and Show in Finder reveals it on the Mac. In the Library, clicking a chat shows its source too; Open from there goes to the chat.
-
Rotli Web: it is a vault you connect, and the words now say so — “Connect a vault on this computer”, “Import a copy of a vault”, “Your vault needs permission again” — instead of “folder” everywhere.
-
Rotli Web: the Files button is back in the sidebar footer. It opens the Library, the vault’s file browser (the Mac app’s Files reveals the vault in Finder, which the web cannot do, and the button had simply gone missing).
-
Rotli Web: Chat stays behind the setup dialog until Rotli Helper answers AND takes the pairing. A helper that refuses the token (a reinstall printed a new code) or does not answer no longer opens a chat that cannot send: the Chat segment says what is wrong, the dialog names it, and Check again re-runs the whole pairing check. Boot re-checks the token too.
-
Rotli Web: when the connected folder needs the browser’s permission again, a bar at the top of the sidebar says so and offers Reconnect, and stays until the folder is back. Before, a passing notice said it once and the app quietly ran on the last copy in browser storage — older chats, and none of the per-chat models the Mac app keeps in the folder’s settings, so every chat showed the default model’s mark.
-
Chat: a chat whose model was saved under its old label (for example “Gemini 3.5 Flash (Medium)”) shows Google’s mark again instead of “this Mac”.
-
Chat: Antigravity (Gemini) chats take image attachments. Google’s agent advertises image prompts, so Rotli now sends attached images as prompt blocks beside your text instead of refusing them; an agent that advertises no image prompts is refused in words before anything is sent.
-
Chat: a sent message shows each attached image as a small
#1,#2chip where the message names it, matching the number on the thumbnail above the input, so you can see where an image was added.
Fixed
-
Rotli Web: reconnecting a copy now takes. With a copy connected, the page’s vault IS the copy, so the reconnect saved the new copy inside the old one (as
.rotli/web/vault-import) and reloaded the old one — nothing changed. The new copy now goes to the browser’s own storage, and the old copy is retired first so its save-on-page-hide can never write again (Forget too). -
Rotli Web, folder mode: a file being written is never read half-way. Chromium swaps a file in when a write closes, and a read landing inside that window threw; when the model backfill rewrote a chat at boot while the notes listing read it, the listing failed and the window opened on “Untitled”. Reads and writes of one path now take turns in the folder adapter, for every writer (chats, notes,
.rotli/). -
Chat: a chat whose first message was only an image no longer takes the image’s storage path as its title.
-
Image drops on a chat whose model cannot see images now show a modal error before importing anything. Choose an image-capable model and drop again to attach. Native drops now reach the import handler through Tauri’s webview event channel, restoring the path disconnected when multi-webview support was enabled. Finder, file-promise, and image-byte drops share the existing import grants; private browser child views cannot import into the workspace.
-
Drag the macOS screenshot thumbnail straight into a note or a chat. The floating preview after ⌘⇧4 / ⌘⇧5 used to land as “Nothing imported”: it hands over a promise of a file, never a path, and Rotli only read paths. Rotli now reads the drag itself — it calls the promise in, waits for the screenshot to be written, and then imports it exactly like a file dragged from Finder, at the point you dropped it. An image dragged out of Safari, Chrome, or Photos works the same way: the picture’s own bytes are saved as a PNG named for the moment you dropped it. Staging files sit in the system’s temp folder and are swept a day later. Set
ROTLI_DEBUG_DROPS=1to have the app narrate what a drag carried. -
Editor: copying from a note now puts the note’s own Markdown on the clipboard as plain text, so a paste into another note or a chat renders exactly what you copied (headings, tasks, lists). Before, the plain text was a readable rendering (“☐ task”, headings as bare lines) and a pasted note lost its structure. Rich targets (Docs, Notes, mail) still get HTML.
-
Editor: a parent task’s subtask pill (“0/1”) printed its digits over the words before it on a nested task; the pill keeps its digits inside its box.
-
Editor: a wrapped task line landed its second row a few pixels right of the first row’s text. The checkbox now sizes from the line’s font (it matches a radio choice’s size), so wrapped rows align under the text, as bullets and numbers already did.
-
Captures: only a Quick capture (⌥C), a Quick Note, or a merge of captures lands on the Captures board. A chat’s background note — the conversation notes every chat keeps, and the note its header button creates — was born with the capture shelf and filled Captures with “Notes from [[chat]]” cards, even after the Librarian filed it. Those notes now project to where they live. Existing cards keep their shelf: trash them, or add them to Main to graduate them.
-
Chat: a chat whose note shared its title with another note (the same note filed in two areas, or your own note with that name) created one more conversation note every turn and never attached it. The chat’s note is now told apart by its link back to the chat, and a chat whose note truly cannot be found writes nothing rather than minting a duplicate; its note button still recreates one on request.
-
Chat: leave a chat while it is thinking and come back, and the thread now shows the working row again and the reply when it lands. Before, the remounted chat showed only your message until the tab was closed and reopened, even after the sidebar said Done: the run settled and saved into the earlier mount’s closure and the new one never heard. The run signals the sidebar already reads now carry a “reply saved” count that a mounted chat follows, and the composer holds while a run it did not start is in flight.
-
Delete folder in the Main tree’s folder menu: an empty folder goes away at once; a full one moves its items to Trash (recoverable) and then goes away. Notes are never deleted with a folder. (Real Library directories still cannot be deleted from Rotli; that needs a Rust command that routes to the OS Trash and is tracked separately.)
-
The note header’s actions are plain glyphs now, not cards: no surface behind the chat, Aa, and outline buttons, hover brings the ink up, and the active one is the accent colour.
-
Ordered-list markers of two or more digits no longer overflow their column: the marker column and the line’s hanging indent widen together, so wrapped text sits under the text, never under the number.
-
All notes says which named view a note belongs to (a muted tag before the date). The list itself stays global, as designed.
-
Copying a selection across a chat copies the messages’ source Markdown, so a paste into another chat or a note renders as the thread did. The browser default serialised the rendered bubbles and the formatting was lost.
-
Dropping a file a surface cannot take (a PDF on a note or a chat) now says it went to Assets instead of vanishing silently, and a chat whose model cannot see images keeps dropped images in Assets and says so instead of discarding them.
-
Multi-select, the same way everywhere: ⇧-click selects the range from the last click in Captures and in the Main tree (the System browser already did this; all three now share one rule). Captures has a Select all button in its header, and ⌘A selects every card while Captures is open.
-
Restore puts a note back where it was. Moving a note to Trash or Archive removed it from Main, so a restored note came back with no Main home and showed up in Captures instead of its folder. The Main slot now stays (the tree hides a note while it sits in a sink), so Restore returns it to the folder it left, and a note opened from Trash or Archive offers Restore in its header.
-
Library, Assets, Archive, and Trash have a Back to notes control at their root, the same one Captures has. The header’s chevron was up-one- folder only and vanished at the root, which is where Trash is browsed.
-
Captures → Make a note (and Merge N into a note) works in a memex vault again. It wrote straight into the literal Inbox folder, which is not a writable surface there, so the create was refused and the button did visibly nothing. The merged note now goes through the same router as every other new note (memex staging when writable, else Inbox), and a refusal is reported in the sidebar instead of swallowed.
-
rotli.co theme studio: the twelve environment orbs rendered as blank paper circles in production because their colours rode inline
styleattributes, which the site’s Content-Security-Policy (style-src 'self') blocks. Localastro dev/previewsend no CSP, so the bug was invisible before deploy. The colours are now CSS rules keyed bydata-orb, and the site build fails on any inline style so the class of bug cannot ship again.site/README.mddocuments the Docker prod twin for validating a build under the real headers.
Changed
- Link previews: rotli.co’s social card now carries the waving quokka, the
Baloo 2 wordmark, and the site address; the page publishes explicit Open
Graph image dimensions and type,
og:locale, a theme colour, a 32×32 PNG favicon, and a 180×180 Apple touch icon so iMessage, Slack, and LinkedIn render the card and icon on the first fetch.bun run build:social-cardalso renders a 1280×640social-card-github.pngfor the repository’s social preview.
Cross-platform groundwork (parked)
- Cross-platform groundwork:
security-frameworkmoved under the macOS-only dependency table (the Keychain module already carried a non-macOS stub, but the crate was still requested on Linux and would have failed at link time), and a manual-onlyCross-platform build probeworkflow builds unsigned bundles on macOS, Windows, and Linux runners so the compiler enumerates the remaining portability gaps. It never runs on push. The feasibility document gained a 2026-09-16 re-count of the seams. - Chats browse in the Library. The Library is the vault, so its
chats/transcripts now show there under a Chats folder, marked as chats, with the chat glyph, opening as chats. All notes and search keep hiding them, as before. On the web in folder mode the same folder appears. - The public site footer now includes a Featured on Launch Llama Tools badge.
[1.0.0] - 2026-09-15
Rotli 1.0.
Changed
- Updates no longer re-run setup. Every 0.x update used to send an onboarded install back through first-run setup. Setup now runs only on a fresh install, or when you choose Settings → Reset & re-onboard.
- Marketing landing: plain Paper hero ground (no coastline backdrop). The hero
plays the full promo muted on load with a sound toggle, slightly larger in
the layout and bled to the right edge. Theme studio shows a Light | Dark
grid of small orbs colored from each environment’s ground and accent; they
auto-cycle all twelve environments and any orb jumps to it. Theme captures
are cropped free of the window bezel. Privacy is an open wider layout
without a surrounding card. The Workspace section is now “What’s in the
alpha” (the capture ribbon is gone). The site calls the release an alpha,
not a beta, and the whole page sits on the Rotli Warm Light ground: the
hero no longer switches to a Paper-white band and the one white card is
gone. A new Organize section leads with Librarian + views: turn the
Librarian on, work from Main or a named view, and keep the vault organized
underneath. The companion block is a coverflow carousel: the current quokka
in the middle with the previous and next ones blurred at the sides, cycling
through real, selectable combinations (body presets and a custom hue, the
plain line drawing, glasses or a bucket hat in default or custom color,
black or white line work, real poses) rendered from the app’s own placement
rules by
scripts/build-companion-showcase.ts. Dots or the side figures pick one; it pauses on hover and never auto-advances under reduced motion. The hero no longer flashes a playback error when a muted autoplay attempt is merely interrupted. The small eyebrow labels above each heading are gone; every section sits on the same page grid (the privacy block no longer spills past the gutter); sections rise in gently as they scroll into view (off under reduced motion and without scripting).
Fixed
- Documents no longer flicker while typing. The editor resized its page canvas by one pixel after every keystroke to force a repaint; it now does so only when a table, image, or drawing is added or removed.
- Tab types a tab in a document. Tab still nests list items and moves between table cells; in an ordinary paragraph it now inserts a tab (saved as a Word tab) instead of swallowing the key.
- ⌘A selects the whole document. Select All from the keyboard or the Edit menu selects every paragraph in one press (it used to act on the editor’s hidden input, or take only the current paragraph), and typing replaces all of it. Toolbar fields keep their own Select All.
- ⌘Z and ⇧⌘Z undo and redo document edits. The Edit menu’s Undo and Redo reached only the editor’s hidden input, so nothing changed on the page.
- A saved document is always valid Word XML. A stray control character typed into the page (Ctrl+A in the editor inserted U+0001) was written verbatim and made the file unreadable; such characters are now dropped on save.
[0.95.1] - 2026-09-14
The 0.95.0 review round: hotkeys, links, lists, documents, the tour, drops, and launch gates for features that are coming soon.
Added
-
Copy an image or file in Finder and paste it (⌘V) into a note or a chat: it goes through the same import as a drop. Before, a note ignored the paste and a chat pasted the file name as text.
-
Settings → About Rotli, with the installed version and a link to sethmedina.com.
Changed
-
Inline code shows as a quiet monospace chip again, so backticked examples in the lessons read as code.
-
⌘E toggles inline code and ⌘⇧X strikethrough by default; format bar tooltips show your current bindings.
-
Links:
www.hosts, email addresses, and bare domains such assethmedina.comlink on their own (file names such asnode.jsandfile.mdstay prose),[](url)shows its url, a scheme-less address opens ashttps://, and a link that can’t open says so instead of a silent dead click. -
_text_is italic, like*text*; underscores inside words (snake_case,__init__) stay as typed. -
Brackets, parentheses, backticks, and
**==~~pair while you type; typing the closer steps over it, and[[still opens the note picker. -
Lettered lists:
a.andA.items count a→b→c, continue on Enter, and strip cleanly in plain copy and read-aloud. -
Spreadsheets (XLSX), the Mermaid diagram tab, and read-aloud are not in public builds yet. The New-tab chooser shows Sheet and Mermaid diagram as “Coming soon”;
/Sheet,sheetfences, opening an .xlsx, and chat-created sheets say they are unavailable. CSV editing and Mermaid fences in notes still work. -
Settings → Connections has shorter web-research copy and lists the Grok Bot plug-in and MCP as coming soon; Settings → AI Models shows Voice as coming soon.
Fixed
-
Documents can be named and renamed. A new Document asks for its name first, like a board, instead of arriving as
untitled-<number>.docx; Rename… on a document’s row or tab renames the file, keeps.docx, follows it in Main, views, and open tabs, and says so when the name is already taken. The document’s first-save.bakbackup moves with it. -
Rename… on a board’s sidebar row works when the board isn’t open in a tab; it opens the rename dialog instead of silently closing the menu.
-
Formatting stacks: ⌘B then ⌘I makes bold italic instead of swapping bold for italic, underline or highlight inside bold or italic renders instead of showing raw
<u>tags, and strikethrough on inline code wraps outside the backticks. -
The
[[note picker stays open with “No note named …” when nothing matches, so Escape closes the picker instead of hiding the window. -
Settings and setup selects, including AI Models’ default-model and preset menus, draw the app’s own rounded control instead of the native macOS popup.
-
Turning one mark off a stack (⌘I on bold-italic-underlined text) removes only that mark instead of inserting stray stars.
-
⌘I, ⌘U, ⌘[, ⌘] and ⌘⌥ arrow pane focus work in Markdown notes again. In 0.95.0 the editor’s built-in shortcuts swallowed them, and ⌘U could even undo your last bold.
-
The format bar’s B button no longer lights up for an unclosed
**. -
⌘W, ⌘1-9, ⌃Tab, ⌘⇧T and ⌘D pressed while Library, Assets, Archive or Trash is showing now bring your tabs back into view instead of acting unseen.
-
New folder in the vault picker opens a folder that already exists instead of showing “File exists (os error 17)”.
-
The Welcome note teaches autosave (there is no ⌘S for notes) and ⌘T for a new note; the empty-pane and empty-list hints say ⌘T too.
-
Setup’s Librarian model menu and the provider default menus use the same select style as Settings.
-
The chat model picker and reasoning menu have a visible border and the floating-surface corner radius.
-
The guided tour dims the app with one scrim and one accent outline around the control. It no longer shows seams, a pulsing halo, or a doubled focus ring, and selected controls keep their look. The dimmed app no longer blocks clicks or Finder drops while the tour is open.
-
A Finder drop is no longer taken by an overlay above the note or chat. A drop that only reaches Assets now says “Saved to Assets”, and a drop of folders says nothing was imported. Before, both did nothing you could see.
-
Skipping app setup after an update no longer turns Stay open and Show in Dock back off. That reset made the window hide as soon as you clicked Finder.
-
DOCX: bold, text color, or highlight chosen with no selection now applies to the text you type next, and highlight plus subscript/superscript survive save.
-
DOCX: ⌘B/⌘I/⌘U and the other format shortcuts reach a document pane.
-
A file whose details can’t be read now says so instead of “Read-only”.
-
Claude, Codex, and Gemini chats answer general questions from what the model knows instead of refusing because the web is off. They search your notes for questions about you, your work, or an attached note, and mention the globe once when an answer depends on live data.
-
The chat model picker is compact (340px, single-line rows, a narrower provider rail), has a visible border, and opens beside the model chip when the window has room.
-
Welcome lessons you never edited now pick up copy fixes the next time you open the Welcome folder; lessons you changed are left alone.
[0.95.0] - 2026-09-13
Three fixes from a computer-use test of the installed 0.94.0.
Fixed
- Clicking the blank space below a note that ends with a wikilink no longer opens that link; only a click on the line itself does.
- Escape in the color or
[[list closed the list AND fell through to the app’s Esc ladder, which could hide the whole window. A key the editor has already consumed no longer reaches the app chords. - Librarian Activity rows now name the lane and model that filed the note (“Claude · Claude Opus”), not only the day and time.
[0.94.0] - 2026-09-12
The Librarian lane actually works: the choice persists and reaches the daemon, the Librarian picks its model, and the Antigravity setup says what it is.
Added
- The Librarian chooses a model, not only a lane: Settings → Librarian and the first-run Models step show the lane’s model list once a connected client is chosen. Unset, the lane’s chat default applies.
Changed
- The Antigravity setup copy says what the lane actually is: Google’s ACP
agent that Rotli downloads and signs in from Settings → AI Models →
Antigravity, separate from the
agycommand line and the Antigravity IDE.
Fixed
- 0.93.0 wrote
organizerModel: "local"to settings regardless of the Librarian choice, so the daemon never used a connected lane and the Settings control reverted to On this Mac on relaunch. The choice now persists and reaches the daemon.
[0.93.0] - 2026-09-12
The second review round on the Welcome kit: the Librarian may file through a connected client you chose, setup knows your Mac before the Models step, the editor’s color list and result colors behave, and Main’s new-note and drag rules follow what is open.
Added
- The Librarian can file through a connected client you chose: Settings → Librarian and the first-run Models step offer On this Mac plus every signed-in Claude, ChatGPT, or Gemini client (Cursor never files notes). Two consents gate it — the choice and the lane’s switch in Connections — and Rust checks both every cycle, so a chosen-but-off lane files on this Mac and says so. The call rides the same seam as chat (provider policy, secret scan, model allowlists); secure and locked notes are skipped before any prompt exists. When Gemini is signed in on this Mac, the Models step proposes it as the Librarian; the lane still waits for you to turn it on.
- First-run setup probes local models and signed-in clients from its first screen, so the Models step opens already knowing what this Mac has instead of “Checking…”. Gemini is named in that step’s heading and copy.
- A note dragged from Main onto a pane opens there: the pane center or its tab strip adds a tab, and an edge carves a split holding the note, with the same dropzones a dragged tab shows. Folders and gathered selections still move only within Main.
- A color-only result pair such as
[:purple][:accent]now renders as Yes and No in those colors, the way[:blue|:green]already reads as a switch.
Changed
- The guided tour’s spotlight is unmistakable: a thicker accent ring with a breathing halo, and the highlighted control itself lifts with a tint and accent outline.
- New (the header button, ⌘T, and the chooser) files the note beside the note that is open, and at the Main root when nothing is open. The last folder clicked in the sidebar no longer decides, so a note created on an empty window no longer lands inside the Welcome folder. Inside a named view the same rule applies: the view stays the context, and a merely selected view folder no longer nests the new item.
- A result row with three or more answers gives every uncolored answer its own color from a fixed rotation (blue, purple, orange, cyan, pink, yellow, brown, green, red), skipping colors chosen by hand and repeating only when the rotation runs out. Rows that used to show every answer in the accent color now show distinct colors; the source text is unchanged.
- A resolved wikilink reads as a link: a solid accent underline instead of a dotted one, and the row tint on hover. Unresolved links stay dashed and muted.
Fixed
- The color list did not open for the first box typed at the start of a line
(
[True:grebefore Space expands the row); it opened only after a list marker or a second box. It now opens for the first box too.
[0.92.0] - 2026-09-12
The Welcome kit release: every lesson teaches the typed syntax, a guided tour points at the real controls, and the editor gains pickers for colors and wikilinks, typed tables, and placeable choice panels.
Added
- A guided tour after first-run setup points at the real controls: New, Main and its view picker, search, Aa, Chat, and Settings. It is an overlay the app stays live under; Skip, Done, or Escape end it, and Settings → General → Show me around (also in ⌘K) runs it again. The welcome note and the views lesson point at it.
- Multi-choice panels can sit left, center, or right. The
[##?]prompt row shows a Left/Center/Right control on hover or when the caret is on it; the choice is written into the marker as[##?:center]or[##?:right], and the bare marker means left. The panel is never wider than 80% of the writing measure, so the placement always shows. - Label colors: typing
:inside a result or toggle bracket opens a color list in rainbow order (red, orange, yellow, green, cyan, blue, purple, pink, brown, black, white, neutral, accent); arrows or letters narrow it, Enter, Tab, a click, or the keys 1–9 and 0 choose. Six names are new (orange, cyan, pink, brown, black, white), each tuned per light and dark scheme. - Wikilinks: typing
[[opens a list of matching notes (titles first, then aliases); Enter, Tab, or a click completes the link and closes it with]]. The links lesson points at it. - Tables: Enter at the end of a typed
| a | b |row writes the delimiter row and a first empty row, so a table starts without knowing about dashes. Shift+Enter inside a cell adds a line break (<br>in source). ⇧-click selects a block of cells and ⌘-click (Ctrl on Linux) adds or removes one; Delete clears the selection in one edit and copy writes it as tab-separated text.
Changed
- First-time setup always opens in Rotli Light with the quokka wearing no accessory, including when a version update runs setup again on a personalized install; the appearance step is where the choice is made. Skip, Settings → Reset & re-onboard, and a fresh install now share that one default instead of resetting to Paper and follow-macOS, and the Rotli family leads the theme picker in setup and Settings → Appearance.
- The Welcome folder’s lessons now show how to type each control as
backticked source (
[][],[True][False], color suffixes and hex,[#],[##?]+[##],[|],[True|False],[:blue|:green], a typed table row,[[) instead of only rendering the finished controls. Existing vaults keep their edited lessons; Settings → General → Open welcome folder reseeds only missing ones. - A bare
[##?]prompt written under 0.91.0 now renders its panel at the left instead of the right; add[##?:right]to keep the old placement.
Fixed
- Pressing ↑ or clicking just below a multi-choice panel or a table landed one line off, because their vertical spacing was a margin the editor’s height map could not see. Spacing is now measured (a block spacer for panels, padding for tables), and a guard keeps vertical margins off editor lines and block widgets.
- The development app is named “Rotli (Dev)” and paints its blue Dock icon
from the Rust shell at launch, so a
bun run dev:appinstance is never mistaken for the installed app even before the webview loads. - The ten-note Welcome walk in the launch E2E suite declares a slow budget so the hosted runner no longer times it out.
[0.91.0] - 2026-09-11
Launch preparation
- The website focuses its public copy on notes and optional chat, hides private source links, and labels broader features only on the dev site. A captioned HyperFrames promo with synthetic Playground interaction, original music and sound effects sits below the hero; playback is opt-in and has a failure state.
- Stable builds hide Breve in navigation/actions, refuse its native commands, and skip managed runtime/scheduler startup. Development builds retain it; restored Breve preferences cannot reactivate it in a stable build.
- MCP and agent integrations leave production until refined: stable builds hide
Settings → Connections → Remote agents and the Claude Code extension prompt,
refuse the relay commands, and refuse
rotli mcpandrotli agent …from the packaged binary. The plain JSON CLI keeps working. The website shows the MCP guide and the agent lanes only on the dev site. - Signing/notarization now require owner authorization for the exact promoted source and successful hosted CI before Apple uploads. Apple submission/log evidence is retained privately; public notary evidence excludes identity/paths.
- Repository and deployment-context privacy tripwires, redacted secret-scan commands, and owner-only main/dev protection payloads are available. Actual branch protection still requires an eligible private-repository GitHub plan.
Added
- Every new vault starts with a Welcome folder in Main: the welcome note
plus nine guided lessons (tasks, results, choices, switches, tables, links,
views, files, AI) as ordinary Markdown notes in
wiki/Welcome/. They open from the left menu and edit like any note. Settings → General → Open welcome folder restores any lesson you removed and opens the welcome note; opening an existing vault never writes. This replaces the session-only Playground tab (lesson dropdown, Raw Markdown and Save controls), the named-view import, and the separate practice vault. New vaults therefore start with sample content, reversing the earlier “no sample content on ordinary vault creation” rule. - Vaults can be removed from the sidebar’s vault switcher: each row’s overflow menu offers Remove from Rotli… behind a confirm step. Removal only disconnects; the folder stays on disk, and the active vault must be switched away first. Named views can be deleted from Main’s view picker (Delete a view…) without switching into them first.
- A development-only browser onboarding review, fresh-vault E2E coverage, a Welcome-folder site walkthrough, and reusable landscape/portrait Remotion films.
Fixed
- Task checkboxes sat 24px left of the H1 and paragraph edge: the inline-block
checkbox wrapper inherited the task line’s hanging
text-indent. The wrapper now resets it, and fresh-vault E2E asserts every checkbox, marker, and control starts on the H1 edge in all twelve environments. - Site screenshots use fresh 3× lossless captures, and companion illustrations are rendered from their canonical SVGs at 1536px for clear Retina display.
- Hovering a task no longer places the block drag handle over its checkbox.
- Empty vaults keep non-note workspace tabs visible, and vault activation finishes before onboarding advances to model setup.
Removed
- The onboarding “Try a practice vault” option and its scratch-vault command. Every vault now starts with the Welcome folder instead.
Changed
- Removed the decorative quokka above the coming-soon page’s introduction.
- The dev-site hero blends its coastline photograph softly into Paper. The coming-soon page shows the Rotli Light Welcome lesson, introduces guided practice, and keeps its compact mobile layout and GitHub development link.
- Mermaid Visual editing is development-only while View and Code remain available in production. Site/provider copy reflects current supported capabilities and distinguishes beta preparation from release availability.
Changed
-
The coming-soon page is pinned to the Rotli light environment with no appearance toggle, and its layout is mobile-first: a compact quokka above the copy on phones and tablets, the framed quokka beside the copy only on desktop.
-
The marketing site shares one header and footer across the landing, MCP, and coming-soon pages, shows the GitHub mark in the header, says “open source under the MIT license” in the footer, and offers “View on GitHub” beside the download slot. Unused site-local artwork and captures are gone; the site now reads every quokka from the app’s canonical assets. Dev deployments add an
X-Robots-Tag: noindexheader. -
The marketing site stays in Rotli Light regardless of operating system or saved appearance. The hero uses Paper, and theme showcase selections only change the preview inside that section.
Changed
- The marketing site now deploys on Railway (Caddy-served static build) instead
of Cloudflare Workers, with a build-time
SITE_MODE:coming-soonis therotli.coholding page,devis the fulldev.rotli.cosite with no download and no indexing,fullis the launch site. robots.txt and the sitemap follow the same policy;wranglerand_headersare gone.
[0.90.0] - 2026-09-05
Added
- Adjacent labeled boxes now render as source-backed exclusive result buttons:
[True][False], or colored forms such as[True:green][Draw:#E3B341][False:red]. Uncolored binary labels default to green/red; accent, blue, green, yellow, purple, red, neutral, and strict three- or six-digit hex colors are supported. Selection writes a portable leadingxto the chosen box, keyboard focus survives the rerender, and invalid or ambiguous source fails closed. [#]now creates exclusive radio groups,[##]creates independent square multi-select options, and[True|False]or compact[|]creates a portable switch with explicit source state. The new controls support pointer and keyboard activation, preserve focus, and remain literal inside backticks.- Compact sidebar, tab, and editor-header actions now keep at least a 24px pointer target, and icon labels appear for keyboard focus as well as hover.
Fixed
- Labels beginning with
Xremain literal; a lowercase literalxprefix can be escaped. Hash choices accept uppercaseX, and copied choice prompts no longer retain their hidden marker. - Labeled results now offer the same optional reason action as compact results. Seeded Welcome lessons stay in Library instead of Captures.
- Updated compatible transitive fflate and fast-uri dependencies for archive bounds and URI-parsing security fixes.
- Typing a bare in-progress or completed task marker (
[/]or[x]) and then Space now adds the portable Markdown list prefix while preserving that state, just as[]already did. Single-task completion now uses the active theme accent instead of pass/fail green, and keyboard activation retains focus so repeated two- or three-state cycling remains possible. The separate[][]result control keeps its green pass and red fail semantics. - Enter after an in-progress task now starts an unchecked task instead of
leaking
[/]down the list. Arrow-left can expose the raw state mark, and a one-second hover on an empty task reveals an accessible In progress action. Completed single checkboxes are solid accent fills without a check glyph. - Compact results cross out the rejected side after a choice,
[##]rows read as a grouped multi-choice panel, toggle colors accept[:blue|:green], and backticked control examples render as plain source text without a code chip. - Purple is now a token-backed named result/toggle color, including
[:blue|:purple]. Grouped[##]choices now use a compact right-aligned measure, even panel gutters, calmer selected rows, aligned controls, and an optional[##?]question row. Backticked examples render as ordinary text, and the Welcome folder is discoverable in General settings.
[0.89.0] - 2026-09-03
[0.88.0] - 2026-09-03
Fixed
- Mermaid diagrams inline in a note (pie, bar/line charts, sequence, flowcharts) drew at less than half size in the top-left of their card: Mermaid’s
width="100%"SVG fell back to the 300px default inside the shrink-to-fit stage while the fit math assumed the diagram’s real size, and the card’s own padding then shrank even small diagrams. The SVG is now laid out at its natural size and the fit pads by the same 12px the card does — a small diagram renders at natural size, centred; a wide one fills the card. - A
```svgfence that carried only aviewBox(no width/height) collapsed to an empty card; it now fills the card’s width and keeps its aspect ratio.
[0.87.0] - 2026-09-03
Changed
- Test suite and tooling audit (2026-09-03):
bun run verifynow mirrors CI’s first steps (frozen installs, dependency convergence and license checks, a blocking chromium check); the release gate looks up CI by commit with a bounded retry and asserts the commit is onorigin/main; Playwright runs on four workers in CI with the GitHub reporter; Linux CI type-checks the Rust crate so its non-macOScfgblocks compile;Cargo.tomldenies warnings locally; oxlint regains itsunicorn/oxcplugins plus four type-aware rules and alocalStorageban;scripts/*.tsis typechecked; oxfmt coversscripts/**/*.mjsandvite.config.ts;check:design-systemrejects undefinedvar(--x)tokens (twelve fixed); the coverage ratchet can only rise; the source-shape ratchet counts assertions; the site declaresclsxdirectly so its prerender build resolves insidesite/under bun’s isolated linker; new fixture tests covercheck:ratchetsandcheck:window-events;check:structurefails when a Breve runtime test is not intest:breve;check:code-shaperejects control bytes in source and macOS-only CodeMirror chords in e2e. Tests: the provider policy test names and pins every admitted lane (Antigravity included), the appearance broadcast and Antigravity service have unit tests, Settings → AI Models has an e2e spec, and stale source-shape pins were retired. Details:docs/architecture/test-suite-audit-2026-09-03.md.
Fixed
- Ordered lists count on their own: deleting an item closes the gap, a Tab-nested run starts at 1 and counts up, and the toolbar’s numbered toggle no longer leaves “1.” on every line. One renumbering policy (
src/editor/listNumbers.ts) rides inside every user edit as a transaction filter — one undo step, caret preserved; undo/redo and programmatic loads pass through untouched. - Copy is a true copy: the clipboard carries the selection as readable text with its numbers, bullets, and task boxes, and as real HTML (nested
<ol>/<ul>, headings, quotes, code) with images inlined asdata:URLs — so a paste into an AI chat, Google Docs, or Notes keeps the list and the picture. Images resolve through a guarded corpus command and the host’s clipboard plugin. - Dropping a file from Finder onto a note draws a drop line under the pointer while the drag hovers, and the drop lands where the line was — or in the editor the drag last hovered, or at the focused note’s caret — instead of silently filing the image into storage when the coordinates missed the editor.
[0.86.0] - 2026-09-03
Fixed
-
Tables follow the pane and show their resize handles. A table with saved column widths overflowed the editor instead of following a narrower window; widths now scale down together to the space available (never below a column’s floor) and grow back with the pane, and tables without saved widths wrap to fit before they scroll. Hovering a column or row edge shows a visible grip that stays lit through the drag. Deleting or moving a row or column no longer throws the view to wherever the caret last was (often the bottom of a long note); the caret stays on the table.
-
A note that changed on disk no longer freezes, and never blocks quitting. When something other than the editor rewrote an open note — a task ticked from the Tasks view, a chat edit, the Librarian, another app — the next autosave hit a revision conflict that never cleared, and ⌘Q refused with “Rotli stayed open because some changes could not be saved”. Rotli now folds the two versions together when they touched different lines (the common case) and saves on. When both sides changed the same lines, quitting keeps your unsaved edits as a sibling note titled “… (unsaved edits
Added
- Antigravity is back as a connected lane, through Google’s official ACP
agent. Settings → AI Models → Antigravity installs the exact runtime
Google lists on the Agent Client Protocol registry (pinned SHA-256 and size,
Apple Silicon only) and signs in with the agent’s own Google flow in your
browser; Rotli never sees the credential. Chat turns ride the same
one-shot, no-tools ACP transport as Cursor, with the model picked per turn
from the account’s own list (Gemini 3.8 Flash and 3.7 Flash, three thinking
levels each;
@geminior@antigravityconsults it mid-chat). Off by default and last in the list; the card states Google’s FAQ position and the DeepMind statements so the account risk is a stated choice. Breve keeps refusing every connected provider. Decision record:docs/decisions/2026-09-03-antigravity-official-acp-lane.md.
[0.85.0] - 2026-09-02
Added
- Breve says when briefs stop arriving. The scheduler’s job ledger now
reaches the app as per-routine health: the Breve rail status, the Today
page, and the Routines page all say “No brief for N days — morning is
failing:
” instead of “Managed by Rotli” while every slot fails (which is what happened silently from 2026-08-16 to 2026-09-02). A failing slot is retried three times (about fifteen minutes), then left for the next slot, instead of every five minutes all day; a longer outage is the doctor’s Signal proposal to rerun. - Breve’s PDFs match your Rotli theme. The PDF appearance now defaults to “Match Rotli”: the app writes its live theme tokens (any of the six families, light or dark, plus your accent) into the routine config and every new brief, topic brief, and email render uses them. The four named palettes and Custom remain as explicit choices.
- Chat’s “create a PDF” uses the same themed renderer. A PDF artifact is now a readable document — title, headings, lists, task boxes, quotes, code, tables, links — in your theme, through the same lane the briefs use; the plain-text macOS exporter remains the fallback when no Chromium-family browser is installed.
- Breve is a labelled segment of the sidebar switcher (Home · Chat · Breve) with a default shortcut, ⌘⇧B (remappable). The vault switcher and the utility footer stay visible while you are in Breve, so Settings and the Librarian are never more than one click away.
Changed
-
Breve reads and writes off the main thread. The snapshot, config, watchlist, brief-instruction, and delivery-settings commands were plain sync commands, so a brief-library scan ran on the UI thread every 30 s while the lens was open and again after every save.
-
On-demand renders honour the chosen PDF palette. Every runtime entry point now resolves the routine config the app writes; the old fallback pointed at a file a Rotli-managed vault never has.
-
The brief prompt is vault-scoped.
SKILL.mdno longer hardcodes~/memex-vaultfor the inbox, storage, and PDF paths; they are templated per vault like the runtime home already was. -
Honest run logs. The brief wrappers log “on-device writer”, not “claude (sonnet)”, for the step that runs the local model.
-
One live theme signal for every embedded engine. Excalidraw boards and embeds, sheet editors, and chat Mermaid diagrams now follow the applied theme through one shared hook instead of each re-reading the OS colour scheme or watching the document on their own; a System-mode OS flip now re-themes an open board.
-
Debt that can only shrink. New lint-chain guards from the code-quality audit:
check:ratchetsholds per-file line ceilings for every source file at or above 600 lines, the count of source-string test assertions, dated provenance comments, and per-directory test-coverage floors;check:dup:gateturns the duplication miner’s cluster count into a ceiling;check:window-eventskeeps every cross-window event documented indocs/architecture/window-events.mdand wired on both sides;check:architecturenow allowlists (and shrinks) the components that import the Tauri adapter directly, keepsprefers-color-schemereads to the theme owner, and keeps raw query invalidation inside services;check:docsfails a CARL rule whose source contract changed after its last review (known backlog in.carl/freshness-debt.json) and any adopted or undated staging entry;parity.jsonnow pins the “Secure notes” folder name, the title-strip markers, the attach picker’s image list, and the video list on both sides of the IPC boundary. -
The proof chain is stated once. The
verifyskill,CONTRIBUTING.md, and the AI workflow guide all point atbun run verify(CI’s local twin); the four-theme lists in the PR template, contributing guide, and CARL design rule now name all six families.
Fixed
- A note created in the Quick Note window is a full note again. 0.84.0 taught the Captures board to claim secure-at-birth notes that still carry the capture shelf, and a new Quick Note has exactly that shape, so it landed in Captures and left All notes until it was starred. The main window now files a newborn Quick Note into Main immediately (hidden while blank, like a ⌘T note), which is the one rule that separates full notes from captures. Notes created in the Quick Note window while on 0.84.0 sit in Captures until you add them to Main or star them.
- Quick Note and quick-capture windows follow every appearance setting live. Only the theme, accent, and quokka choices used to travel from the main window; the syntax palette, per-note typography, hotkey hints, time format, and rebound keys went stale in the floating windows until relaunch. Main now broadcasts its whole settings snapshot on change.
- Your quokka line colour sticks. Choosing Black in Settings → Appearance silently reverted to Auto on every relaunch, the Auto and White buttons were both labelled “White”, and Auto had no swatch. All three choices now persist, are named honestly, and an explicit Black or White is honoured in every placement (empty states, rest state, chat) — not only in the Settings preview. Auto still follows the theme.
- Lively chat welcomes keep their time-of-day pose. The preferred idle pose was overriding the morning/afternoon/evening scene the Lively style promises; Calm keeps the preferred pose.
- Skipping onboarding resets the whole quokka, including line colour, accessory hue, and idle pose, and the accessory hue slider is hidden under the Line treatment where it has nothing to colour.
- Quick Note settings copy names the real keys. The picker is ⌘P (not ⌘K) and favorites cycle with ⌘] and ⌘[.
[0.84.0] - 2026-09-01
Added
/attatchopens Finder for Markdown image attachments. The slash command supports multiple images, is also searchable as/attach, copies every pick into the note’s registered vault, and inserts portablestorage:links.- Notes can embed playable video. Drop an
mp4,mov,webm,m4v, orogvon a note (or pick one through/attach) and it lands as the same portablesource an image uses, rendered as a native player with seeking, the|widthsuffix, the resize grip, and selection. Video and images remain the only preview-only surfaces; nothing about the file is converted. - Slash commands work inside a result’s reason. Type
/attach,/table, or any other command as the last word of a— reasonand the block lands on an indented line beneath the answer; the row keeps its label and reason. - Markdown can hold immediate decisions and one-of-many answers. Type
[][]and Space for a left-check/right-red-X pass/fail pair, with bold result labels and an optional portable— reasonsuffix. Type()and Space for adjacent radio-style options backed by( )/(x). Every click writes to the note, all controls are keyboard reachable, and neither protocol enters the ordinary Tasks projection. - Connected providers now have explicit, user-editable defaults. New setups
start with Claude’s rolling
sonnetalias, Codexgpt-5.6-sol, and Cursorgrok-4.6; persisted choices are validated against each provider’s own native allowlist. Chat can request an attributed independent opinion with@claude,@codex, or@cursor, optionally followed by:model-id, without changing the chat’s primary model. - AI Models now opens with an account-safety disclosure. It explains the official-client boundary, links the reviewed provider documentation, and states why an Antigravity subscription cannot be exposed as a Rotli lane.
Changed
- The dev build is representative.
tauri devnow compiles Rust atopt-level = 1: listing a 250-note vault dropped from 4.6 s to 0.4 s in the dev app (release: 0.28 s), so structural refreshes no longer read as lag that release users never see. - Connected chat now has an explicit official-client boundary. Rotli keeps Claude Code and Codex as opt-in interactive lanes and adds Cursor software chat through Cursor’s documented ACP custom-client route. Cursor runs in read-only Ask mode from an empty scratch workspace, advertises no filesystem or terminal capability, and rejects every permission request. Rotli launches only already-authenticated official local clients; it does not present provider login, inspect provider credential stores, or reuse these clients for Breve, the organizer, or background automation.
- Cursor now exposes its documented model selector. Grok 4.6 is the initial default and Cursor Auto remains an alternative; both still run through ACP in read-only Ask mode with no advertised filesystem or terminal capability.
- Retired Codex choices are gone. GPT-5.4 and GPT-5.4 mini retired for ChatGPT-authenticated Codex on August 31, 2026, so they no longer appear in Rotli or the native model allowlist.
- Cloud background and image work now fail closed. Breve configuration is normalized to registered on-device models, the organizer is local-only, and provider-backed image generation is unavailable while provider-authorized integrations are designed.
Fixed
- Empty Markdown drafts no longer accumulate as
Untitledin Main. A new note stays in its immediate editor tab but outside Main/named-view projections until the first successful non-empty save, when its correctly titled row is filed into the creation context originally selected. Closing ⌘T before background creation/readback finishes now discards the still-blank result instead of filing a late orphan. Existing blank Markdown references are also hidden using exact body-emptiness metadata while their files and Main slots remain intact; an explicitly titledUntitlednote is not mistaken for one. - Main’s right-click Trash action now honors gathered selection. ⌘-selected
rows produce one explicit
Move N items to Trashaction, mixed item kinds use their guarded note/file lanes, and Main references are removed only after the batch succeeds. - Command-T opens the real editor in the original key event. Rotli activates a focused, fully editable pending Markdown tab before file I/O, keeps first- paint keystrokes in its shared buffer, and transfers that draft onto the durable note revision before retargeting the same tab. It leaves the tab closed if the user dismissed it while creation and refresh continued in the background.
- Librarian moves no longer create false editor conflicts. Open buffers adopt same-prose location/frontmatter revisions, and the native save gate can merge a stale complete-file hash only when the current disk prose still matches the editor’s saved baseline. A genuine concurrent prose edit remains a visible, non-overwriting conflict.
- Held-Command tab hints stay in the tab strip. Shortcut badges now honor
overflow clipping, so a scrolled-away
⌘1cannot paint over the Home/Breve sidebar and a partially visible tab anchors its hint at the visible edge. - Command-W closes before the next paint. The frontend registry now owns the shortcut in its original key event instead of waiting on a native event round trip, and large-note save assembly starts after the close paint rather than beachballing React’s unmount commit.
- Finder image drops stay with their note’s vault. Nested editor targets now
resolve reliably, native physical/logical coordinate differences are both
handled, and a byte-backed webview drop remains as a runtime fallback.
Named-root import ids become portable
storage:links, and a failed import reports its reason instead of silently doing nothing. - Quick capture never surfaces the app, and captures stay captures. ⌥C from another app with Rotli open underneath raised the main window over the app you were in; the card now follows the Quick Note law (in Rotli means main was visible and focused, and finishing never force-raises main). Secure-at-birth captures were also filed under “Secure notes” beside curated secure notes; a capture that still carries the capture shelf now projects to the Captures board like any staged capture, with its protection unchanged.
- Command-T no longer refetches the whole vault. Creating a note invalidated every open tab’s body and re-walked the Tasks projection on top of the note listings; a new item now refreshes the listings only, and the remaining structural refresh runs its three round trips in parallel.
- The rest state reads as designed. Its three actions no longer wrap their labels or render as bevelled buttons, and a filled quokka keeps its dark ink on dark themes instead of drawing light body lines under dark accessory ink.
- Dropping an image on a chat attaches it again. The composer read the
imported asset back with a webview
fetch(asset://…), which the ipc-onlyconnect-srcblocks — every drop failed with “Load failed” after the file had already been copied into the vault. Attachments now read back over the IPC byte lane with the same 25 MB ceiling Rust enforces, the drop lane honors the paperclip’s vision gate instead of attaching an image send would refuse, and an.svgdropped on a chat is filed to Storage rather than refused and lost.check:securitynow fails any undeclared rawfetch(undersrc/. - Dropping an image on a note’s header or margins inserts it. Only the text body was a drop target; anywhere else on the note silently imported the file to Storage and inserted nothing.
- Unapplied Mermaid edits survive closing the note. Closing or switching the tab under an open diagram workspace force-closed it and dropped the draft. The draft now waits on the fence it opened from and is restored when that diagram is reopened; Apply or an explicit Discard clears it.
- A secondary click no longer answers a result, selects a choice, or toggles a task. Only the primary button writes to the note; result answers also join the ordinary input undo group.
- Tab, Enter, and arrows on plain lines skip the table scan. The table keymap ran a whole-document table (and nested fence) scan on every press to learn the caret was not in a table; lines without a pipe now return at once.
Removed
- Antigravity and direct Gemini model execution. Antigravity is no longer in the native binary/model allowlist and has no argv, spawn, retry, sandbox, image, detection, Keychain, or Breve resolver path. Old settings are ignored rather than retained as provider state, so they cannot reactivate a Google subscription lane.
[0.83.0] - 2026-08-31
Added
-
Remote agents can opt in to the local workspace without uploading the vault. Rotli can connect the running Mac app to a stateless HTTPS MCP relay for Grok Bot and other cloud clients. Pairing uses independent Keychain client/device credentials, every launch starts disconnected, vault switches disconnect, and an explicit Remove pairing action disconnects and deletes both credentials. The existing secure-note, locked-note, and optimistic-revision gates remain the only workspace policy engine. The single-replica relay has bounded in-memory sessions, no database or volume, and a pinned Bun container. The public site now includes an MCP setup, safety, verification, and self-hosting guide without advertising an undeployed relay domain.
-
The private browser now supports real multi-tab research. While browsing, ⌘T or the pane-strip plus opens another isolated private page, popup links open as sibling tabs, and switching among any number of browser tabs keeps each native session alive until that tab closes. Page titles stay in memory only; URLs, history, cookies, and site data still never enter viewstate.
Changed
- The public site now shows the real Rotli workspace in the open air. A coastal, lightly textured hero replaces the synthetic app mockup, while a privacy-safe browser-demo capture anchors the product story. The theme studio now switches among six real, seeded-corpus captures—one representative environment from every theme family—and remains responsive in both site modes.
- Reasoning controls now follow the selected model, not only its provider. Claude Haiku no longer offers unsupported effort controls; each Codex model exposes only its own effort ceiling, GPT-5.6 Sol/Terra gain Ultra, and Fast appears only for the GPT-5.6 family. Rust validates the same combinations before launching a provider CLI.
- Saved-chat rows have a calmer, keyboard-safe hover action. Recency yields to one overflow button in the same trailing slot, with the existing row menu behind both overflow and right-click. Active rows keep provider artwork at its normal color instead of tinting the OpenAI mark.
- The repository toolchain now runs on Bun 1.4.0. App, site, Breve, CI, release evidence, dependency maintenance, and frozen lockfile checks share the exact stable runtime pin, with matching Bun 1.4 type definitions.
- Bun installs now fail safer and validate faster. Every install root uses lockfile v2 and script-free isolated resolution with a project-local store; lint fans independent checks out in parallel with an equivalent serial fallback, while CI blocks on lockfile convergence and exact Unknown-license drift and retains a combined production-license inventory.
- The Vite 8 build and Oxc gates now fail closed on toolchain drift. Vite uses native Rolldown options, new Rolldown/Oxc warnings fail the production build, Oxlint’s type-aware sidecar and warning ceiling are config-owned, and executable tests prove both Oxlint and Oxfmt behavior rather than only their command strings.
Fixed
-
Connected models no longer mistake Rotli’s own tool scaffold for prompt injection. The frontier prompt is framed as an application request instead of an identity override with a competing “JSON-only system” persona. Real commands inside note or web results remain ignored, while the model is told to continue the requested research from trustworthy evidence rather than making the ignored injection its answer.
-
Finder image drops no longer race their native file authorization. Rust now grants each exact dropped file before notifying the webview, so a valid drop into Chat or Markdown cannot intermittently fail as unauthorized; the same grants remain short-lived and single-use.
-
Antigravity chat uses the CLI’s real model IDs again. Rotli now passes the current
agy modelsidentifiers instead of human display labels, removes the retired Gemini 3.5 choices, and no longer repeats the same stderr tail twice when an empty CLI response fails. -
Long chats no longer mount an unbounded React transcript. The Markdown file still keeps every message, while the active surface mounts the newest 500 and states how many earlier messages remain on disk. Model history and tool scratchpads retain their smaller per-model budgets.
-
Remote-agent transport fails closed at every hop. The Mac connector no longer follows relay redirects, bounds relay responses before JSON parsing, binds credentials to their minted relay URL, bounds the complete 512 KB MCP response plus relay envelope, and makes disconnect/vault switching wait for any in-flight dispatch and delivery. Loopback HTTP uses a timing-stable bearer comparison, and regression tests cover non-loopback binds, stale connector generations, conflicting device tokens, relay capacity, and both route-level and pre-handler Bun body caps.
-
The production quality gate accepts only rules supported by the pinned Oxlint. React Compiler diagnostics remain in their dedicated ratcheted check; the ordinary lint config no longer names rules absent from Oxlint 1.78.0, which caused the Linux production job to stop before the build.
-
An outdated Bun can no longer rewrite Rotli’s dependency graph after rejecting lockfile v2. Plain installs are frozen in the app, site, and Breve roots; contributor guidance now identifies the exact Bun pin and the recovery command before another resolver can downgrade the lockfile.
-
Small decorative Rotlis are crisp again. Settings section accents and onboarding’s quiet edge characters now use one semantic line-art treatment instead of shrinking and fading personalized fill/accessory composites.
-
The side-view walking quokka wears its accessories credibly. The bucket hat’s side art seats on the profile crown with the ear tucked and the back of the head keeping its full fluff, and face-on eyewear clips to a true profile: glasses show a single lens over the visible eye and goggles a single lens perched on the brow — never the splayed pair.
-
Accessory color no longer halos around the glasses. The glasses’ hue layer is painted over the ink frames as deliberate colored frames (the same colored-fill-plus-outline language as the hat) instead of peeking out from beneath them as ragged slivers — the artifact on the model-setup companion.
-
Ocean, Grove, Iris, and Midnight now feel like themselves in light mode. Their light environments were near-white with a whisper of tint — effectively “white with a colored accent.” Grounds, surfaces, chips, borders, and the theme-card previews (and the marketing site’s swatches) now carry each family’s hue in daylight: an airy blue room, a soft green one, lavender, and a cool steel white — with every text pairing measured at or above AA contrast.
-
The prompt-trail paws track your prompts, not the responses. The tracker highlighted a single “nearest” prompt — at the bottom of a chat it marked the reader one up, and answer text counted as “seeing” an exchange. A paw now lights only while its prompt bubble is on screen: two bubbles sharing the screen light two paws, and reading deep into a long answer lights none.
-
The accessory chooser is now three quokka icons with a color row. Onboarding’s dropdown became icon buttons — the bare quokka, glasses, and bucket hat, each a mini preview — with seven accessory-color dots inline once an accessory is on (Settings keeps the full hue dial). Goggles are parked for now: existing companions keep rendering them, but the pickers no longer offer them. The side-view goggle lens also moved back onto the crown where worn-up goggles sit.
-
The Line quokka no longer disappears on dark themes. The line treatment’s ink now follows the environment — near-black on light themes, white on dark — while filled treatments keep their designed dark ink everywhere. Existing profiles migrate automatically (black was only ever an implementation default; no control offered a choice).
-
Ocean, Grove, Iris, and Midnight now show their light/dark preview dots. The onboarding theme cards only had swatch styles for the first two families; the other four rendered empty rings.
-
Onboarding’s Back now answers ⌘←. A setup-scoped
setup.backaction joinssetup.continue; the footer badge advertises the arrow instead of ⌘[, which stays the app-wide notes-navigation chord. -
The bucket hat now actually sits on the quokka’s head in every pose. Front-facing poses no longer chop the ears into floating stubs (each pose’s brim widens to cover them, and the occlusion edges gained flared corners so no clipped fragment survives beside the hat), the thoughtful companion’s hat seats on the crown instead of hovering beside it, and walking and board tuck their side ears under a properly sized brim — which also fixes the detached-hat look on onboarding’s leaning edge companions. The clip beside the brim keeps its safe depth so it can never slice visible cheek fur — the three-quarter poses (thoughtful, listening) cover their large ears with the brim itself plus a wider notch at brim height. Verified visually across all fifteen poses, the onboarding companion and preview sizes, and the 72° edge-lean context.
[0.82.0] - 2026-08-19
Changed
- The agent surface is now uniform across Claude, Codex, Cursor, and
Antigravity. All four tools load the same canonical
AGENTS.md(Cursor natively, Antigravity through a gate-enforced.agents/rules/AGENTS.mdsymlink), reach the same project CARL server (.cursor/mcp.jsonand.agents/mcp_config.jsonjoin.mcp.jsonand.codex/config.toml), and share one repo skills home —.agents/skills/(Agent Skills standard), with.claude/skillssymlinked in for Claude. The CARL server gained an env-gated read-only mode (CARL_READONLY=1hides and refusescarl_stage_proposal) so only Claude stages rule proposals, and a first sharedverifyskill routes every agent to the same proof chain.bun run check:docsasserts the wiring, mirror integrity, skills parity, and read-only behavior (live smoke test). - Claude now genuinely always-loads the canonical agent rules.
CLAUDE.mdbecame a true importing adapter: a bare@AGENTS.mdmemory-import line replaces the former Markdown link, which Claude Code never auto-loaded.AGENTS.mdslimmed to 4.6 KB of real headroom under its 5 KiB ceiling by moving the surface-ownership map intodocs/architecture/ai-context-architecture.md(now the single ownership + budget contract) and droppingREADME.mdfrom mandatory per-task reading.bun run check:docsnewly enforces the bare import line and a 1,000-byte adapter budget soCLAUDE.mdcannot regrow into a second rulebook. - Web research can now stay inside Rotli. A titlebar control and the New chooser open a private browser tab backed by a separate non-persistent native webview. New tabs begin on a start page that follows Rotli’s current light or dark environment, while Settings → Browser selects DuckDuckGo, Brave Search, Google, or Bing as the app-wide default. Only that provider choice persists: the browser accepts HTTP(S) pages, keeps remote content outside Rotli’s app webview and vault capabilities, and discards cookies, storage, destinations, and history with the tab. Settings explains its narrow purpose as quick, private research rather than a replacement for an everyday browser. Breve’s top stories now expose their own clickable Markdown citations in the right column and open them through that same private surface. Its left headline uses fixed breakpoint sizes, so wide windows no longer inflate it and constrained columns step down cleanly.
- The marketing site now explains the complete Rotli workspace. A new product-led story shows the one-folder architecture, editable Markdown and bonus work surfaces, AI privacy boundaries, all six theme families, the optional filled quokka companion, Breve, and the bounded CLI/MCP surface. The responsive page imports canonical character assets, previews light and dark environments interactively, and replaces stale Brain-era screenshots and notes-only positioning with a privacy-safe current workspace view.
- Bun 1.3 now shortens the inner development loop without changing Rotli’s
runtime boundaries. Unit tests run in isolated parallel workers, and a new
test:changedcommand follows Bun’s import graph for focused local checks. Bun.Image, Bun.WebView, the experimental global install store, bundler metafiles, and Bun.cron were evaluated; the raw-pixel, Vite/Tauri, frozen runtime, and durable local-time scheduler contracts remain with their current owners. - Time-based views stay current without multiplying component timers. Dashboard ranges, Tasks sections, Breve schedules, chat ages, and editor timestamps now read one visible-window clock through React’s external-store contract. A lint-only React Compiler ratchet also blocks new render impurity, unsafe ref access, synchronous effect-state updates, and hook suppressions without enabling the compiler in production.
- Dependency review now covers every Bun graph without allowing tooling to
mutate CI. The app, site, and Breve install roots share one three-day
release-age policy and one multi-lockfile audit command. Bun 1.4’s audit-fix
plan, dedupe check, prune preview, license inventory, and package-source diff
are available through a version-gated workflow; mutation requires an explicit
root and
--apply, and compatible audit repair never implies--latest. The moving canary can be evaluated separately but cannot become release evidence. Native development also uses Bun’s parent-death handling so its supervised Tauri and Vite descendants do not outlive the terminal owner. The first reviewed maintenance pass repaired 21 compatible vulnerability findings across the app, site, and Breve graphs, converged every duplicate, and pruned stale local installs; range-blocked residuals remain documented. - Appearance is now a personal workspace studio. Realistic workspace previews make Light, Dark, System, Rotli, Paper & Charcoal, Ocean, Grove, Iris, and Midnight easy to judge; System follows macOS within the one selected family. The optional quokka companion can stay onboarding-only or follow the user through Rotli with a selected body hue, black or white ink, idle mood/pose, accessory, and independently colored accessory layer. Rotli keeps semantic poses in empty states while preserving that personal look; personal idle and completed-chat placements use the user’s preferred mood. The compact mark remains its original line art. Accessory fills now respond entirely to their hue control, stay clipped beneath their selected ink, and become monochrome with Line treatment instead of leaking source color. Long chats can use quiet lines, soft dots, a functional quokka-paw trail, or little ears. Each marker now previews its matching prompt directly on hover or keyboard focus; the unboxed rail and lower-opacity preview stay distinct from the active prompt. The Activity overview now makes proper use of wide panes. Persistent active rows now use a lower-salience accent wash rather than a solid primary-color field. The retired curled-r vector/tile family has been removed from current product and brand-kit surfaces, including Quick Capture and the native menu-bar icon.
- Vaults can be recovered and disconnected without restarting Rotli.
Location settings now uses an explicit two-step Remove from Rotli action that
never touches the vault folder or its files. Deleting the active folder in
Finder automatically opens the first available connected vault on Home; if
none survives, Rotli returns to vault setup and never recreates the missing
folder. The larger switcher gives every vault row its own refresh and overflow
controls, moves Location into the overflow, and replaces New/Connect with one
Connect vault action. ⌘R still refreshes the current vault. Every newly
created vault also opens a real,
editable
Welcome to Rotli.mdnote at the vault root. It stays outside Library and can be trashed through the ordinary note lifecycle. - Antigravity now exposes its complete current model catalog. The connected
lane includes every model reported by
agy models, including Gemini 3.7 and 3.6 Flash at High, Medium, and Low effort, without weakening Rotli’s native provider/model allowlist. - Vault selection now stays inside Rotli by default. Onboarding, the vault menu, and Location settings open a Home-first, directory-only browser with keyboard navigation, direct child-folder selection, new-folder creation, explicit empty-folder guidance, and the real absolute path. Home itself remains visible but cannot become a vault because it contains private app and credential data; Desktop and ordinary child folders work normally. Finder and the macOS picker remain explicit escape hatches for reveal and additional locations.
- A new vault now opens inside the ordinary workspace shell. The Home
sidebar, pane tabs, and titlebar actions remain visible around an editable
Markdown welcome note with a short list of things to try. Holding Command now
badges the titlebar New, Split right,
and Split down controls with their live bindings, and the
+runs the same new-item chooser as ⌘N. - Vault identity is explicit in the pane workspace. The sidebar remains the one active-vault menu, and connected vaults remain switch targets rather than mixing their notes into panes, search, System counts, or AI context. Saved chat state retains its vault identity for safe migration. Entering Breve now swaps only the Coffee/Quokka mode control; New, New folder, and Collapse all remain in the same header positions.
- System stays stable when the active vault changes. The Home sidebar always shows Library, Assets, Archive, and Trash; only their contents and counts change, and connected vaults no longer appear as a separate Folders block.
- Fresh-chat naming now reads as an input, then a title. The optional name has a visible field boundary and keeps “Enter to skip” inside its placeholder. Sending the first prompt immediately retires the field into ordinary title text, using the entered name or the existing first-prompt title derivation.
- Fresh chat starts as a tighter working area. Its greeting, composer, and starters sit lower in a tall pane, while the unsent composer uses a narrower, shorter measure. Once a conversation begins, the ordinary per-chat reading width takes over again.
- ⌘R now refreshes the active vault in every build. It replaces the former development-only webview reload with the same reopen-and-rescan action shown in the vault menu and Location settings.
Fixed
- Accessories now follow the quokka’s selected mood and movement. Generated glasses, hat, and goggles layers contain only accessory geometry and mount to pose-specific face, brow, or crown landmarks. The scarf accessory has been removed. Angled and moving poses no longer leave eyewear behind at the neutral coordinates. The bucket hat now has a smaller fitted crown covering the ears and a soft, downward front brim above the eyes. The rear brim stays behind the crown and head instead of appearing across a front-facing quokka. Dedicated front, three-quarter, and side art keeps the crown and visible brim in perspective across every pose instead of rotating one flat front hat. Filled and Line companions clip ears, head strokes, and preserved detail beneath the hat’s curved lower silhouette without introducing a background-colored patch. Every pose retains its own face and outline below the brim.
- Native development can create, open, link, and switch vaults again. The production-selected vault remains a read-only boot fallback until rotli (dev) records its own isolated selection. Switching an already-connected vault now keeps the process and native shell alive while the active data, Librarian, Breve, and webview caches rebind in place. Switching or creating a vault also keeps the outgoing Rotli vault linked, so it remains available in the vault menu. Selecting an already-linked vault now switches by its registered id instead of incorrectly demanding a fresh native-picker authorization. Connecting another vault now registers it in the running registry without a relaunch, and explicit development configs retain all linked roots instead of collapsing them to one vault on the next launch.
- Every vault change is now a live folder transition. Creating a vault, creating a practice vault, importing a reviewed copy, choosing another notes folder, and selecting a connected vault all keep the process and native shell alive. After the target vault hydrates, Rotli always lands on the Home/Notes front instead of inheriting Chat or Breve navigation.
- A truly empty vault no longer removes the left menu. The empty-corpus branch now renders inside the three-pane shell, and newly created vaults reset inherited collapsed/Breve/Chat navigation before showing their first-use welcome.
- Moved Rotli vaults reconnect by identity on macOS. A machine-local URL
bookmark follows ordinary Finder renames and moves, and startup repoints the
readable absolute-path config only after the destination’s stable
mx_…identity matches. An unresolved stale path returns to vault activation instead of silently binding the legacy~/Documents/rotlilocation.
[0.81.0] - 2026-08-13
Changed
-
Breve now opens as a vault-specific news dashboard. The latest saved briefs form a most-recent-first carousel on the left while Top stories stays visible on the right, with watchlist sources, actions, upcoming routines, and sanitized scheduler activity below. Watchlist has an explicit Refresh last 30 days action: it saves pending topic changes first, generates one in-app brief in that vault in production, and reports its bounded lifecycle through Breve Notifications. Development only previews that action in memory; it does not run a model or write a production vault.
-
Browser is available from New and ⌥T. The New chooser exposes a Browser action alongside Chat and durable file types, and the same action is independently rebindable in Keybindings. It opens the user’s default web browser without creating a fake vault item.
-
Global search now happens in the titlebar field itself. Clicking search or pressing ⌘K focuses the same top field and unfolds results directly beneath it instead of opening a centered modal. A semantic fade quiets the rest of the workspace while leaving the field, results, and underlying content crisp. The field keeps one clean container: the Rotli mark and ⌘K hint no longer sit inside extra chips. Search sections now follow their strongest result, so an exact or prefix filename/title match rises above incidental note-body hits instead of being buried by a fixed Notes-before-Files order.
-
Development builds now keep a recognizable Dock icon. The unbundled
tauri devexecutable sets Rotli’s quokka icon at runtime instead of falling back to macOS’s genericexectile, with a fixed blue background that keeps it visibly distinct from the production app. Its runtime-safe artwork uses the same optical Dock footprint as the production icon rather than filling the entire slot. Release icon choices are unchanged. -
Chat naming now lives in the chat header. Fresh and saved chats share a quiet
view / chat namebreadcrumb instead of putting a second title field above the composer. The fixed header now remains the first row in fresh and saved chats instead of being displaced beneath the welcome area. Ask-first mode focuses that optional header name and Enter advances directly to the message; First-message mode bypasses naming and derives a normalized title automatically. Saved titles remain directly editable in the same header and update their sidebar and tab labels without changing the durable Markdown filename. -
Onboarding now owns the vault and model decisions end to end. Completing shortcuts always proceeds to an explicit vault choice—even in development— with options to create a tagged Rotli vault, review an existing folder, use a practice vault, or deliberately keep a configured vault. Development writes only its isolated vault binding and no longer treats the production fallback as selected. After vault activation, a relaunch-safe final step can install a starter on-device model or connect authenticated Claude Code, Codex, and Antigravity lanes; model setup remains optional and clearly labels connected models as remote. The model step now reuses and lists every registered on-device model, lets users select the MLX default or confirm removal, and exposes the curated install catalog model by model. Back buttons now display and invoke Rotli’s real remappable Back chord across preferences, vault substates, and models. The shared setup frame now keeps its footer fixed across every step; long model or vault content scrolls inside the middle stage instead of moving the primary action. Progress now remains one continuous six-step count across preferences, vault, and models. The model screen groups local models, installs, and subscriptions into compact disclosures with explicit scroll cues, while the slowly alternating edge companions remain present through the complete onboarding flow. Those disclosures now use Rotli’s shared chevron and show the approved Gemma, Qwen, Llama, Phi, Mistral, Claude, OpenAI, and Gemini-family marks beside the models they identify.
-
Onboarding appearance separates theme from mode. The same Charcoal, Paper, Warm Light, and Warm Dark token sets are organized as two families— Paper & Charcoal, and Rotli—with explicit Light, Dark, and System choices. Selecting Light or Dark turns System off; System follows macOS within the selected family. Primary color leads with the environment’s own accent, keeps the existing presets, and adds a persisted, contrast-managed custom hue. Dock companion now leads the window choices, and two partly hidden characters remain at the welcome edges while a slow, low-opacity pair alternates positions; reduced motion keeps the scene static.
-
Chat dates now share the message hover row. The timestamp appears beside Copy (and Read aloud when available) on message hover or keyboard focus, keeping the transcript quiet without separating related metadata controls.
-
Rotli activity and model usage are now separate, honest dashboards. Home opens vault note/chat activity; Chat opens local provider usage. Both lenses offer 24-hour, 7-, 30-, and 90-day ranges, while model usage adds trends, provider coverage, and a model breakdown. Rust scans fixed Claude Code/Codex history directories and returns aggregates only—never prompts, replies, paths, filenames, or session ids. Exact recognized models also show a dated standard-API dollar estimate; unknown IDs stay unpriced, and the comparison is explicitly not subscription billing. The browser twin does not imitate native telemetry. Loading now has a restrained reading state, range changes retain the last complete dashboard, and native scans reuse unchanged histories or parse only newly appended bytes. While a dashboard is open, its sidebar overview card now owns the active treatment instead of leaving a stale Home/Chat or note selection highlighted.
-
The Claude Code docs extension is easier to copy confidently. Its action now lives on the instruction block it copies, uses the standard copy glyph, and reports copied or clipboard-failure state without shifting the content.
-
Long-running model plans read as progress instead of transcript noise. Standard Markdown task lists and provider-style checkbox symbols render as a compact read-only checklist with pending, current, completed, and completion count states. Local and frontier prompts use the same task-list grammar only when a multi-step job benefits from visible progress.
-
General can keep inactive work out of the way without deleting it. Two opt-in, default-off settings can unlink untouched items from Main or move untouched chats into the recoverable Chat Archive after a chosen number of days. Viewing resets the app-owned inactivity clock; pinned and open items stay put, and Main cleanup never moves or edits the underlying file.
-
Chat transcripts render more like structured documents. Assistant headings, nested bullet/numbered lists, quotes, code blocks, attached images, and original send times now have dedicated presentation. General can show message times on a 12- or 24-hour clock, and file-local Command-F opens an in-editor find bar.
-
Settings and sidebar utilities are quieter. The former Hotkeys section is now Keybindings, and the Files/Librarian/Settings footer uses an inset fade and steadier spacing instead of a hard full-width divider.
-
Chat model controls now match the native provider. The model picker is grouped by provider instead of opening one long list. Claude and Codex chats expose per-chat reasoning effort; Codex also offers Standard/Fast service routing. Rust independently allowlists every IPC value before constructing subprocess arguments.
-
Chat activity and Home summaries are easier to scan. Completed runs stay in a separated session Activity lane, chat folders float by newest activity, rows show compact last-chat times, and nested trees gain quiet guide lines. Home starts with factual new-note, updated-note, and selected-model counts for the week; Rotli does not invent a human-vs-AI word split without provenance.
-
Chat and editor controls received an optical alignment pass. The prompt marker bars center in their rail, the composer meets the transcript with a semantic fade, the add control is unboxed, compact Rotli marks use the detailed line art, fresh-chat content sits higher, and the editor return-to- top control matches the floating format bar.
-
Tab bars stay still under the pointer. Hover and active styling now use fixed geometry with reserved close-button space, so neighboring tabs no longer jump. Settings → General can keep readable horizontally scrolling tabs or shrink the full tab set to fit the pane.
-
Fresh chats now feel composed instead of empty. A compact Rotli companion asks “What should we work on?” beside the prompt instead of sitting inside a decorative time-of-day card. An optional onboarding name personalizes that line, and Lively adds one restrained arrival hop rather than a continuous idle loop. Useful vault-aware starters sit beneath a wider, centered composer.
-
Chat artifacts now open where the user expects. The default reuses one right-side working pane for every artifact from a chat; Settings can instead choose a new pane or new tab. Word/document buttons now span the message width and remain attached to the assistant response that presents them.
-
Long chats are easier to navigate and clarify. A quiet left-edge prompt navigator stays open while the pointer crosses into its compact, top-aligned prompt list and jumps to earlier user turns. Hovering or keyboard-focusing a prompt previews its matching rail marker with a lower-opacity accent while the current prompt keeps the stronger state. Every local/connected/hybrid model can surface the same compact clarification bar; the composer groups attachments and web search under one add menu, keeps the model beside Send, and reminds users to verify important model responses.
-
Chat artifacts now preserve the file format the user requested. Word and DOCX requests create real editable
.docxfiles through the managed document workflow; ambiguous “document” requests ask Word versus Markdown. Images generated in the same run are embedded as ordinary editable DOCX media, and generated headings, lists, tables, and spacing use native Word structure. Images, boards, and documents stay closed until selected from the chat’s quiet full-height artifact rail or its compact narrow-pane header menu. Word files now use a recognizable blue Word mark and remain directly clickable as document buttons inside the originating chat. -
Working chats now stay visible without continuous sidebar motion. The Working lane and status dot update immediately when a run changes state, then remain static instead of pulsing for the duration of the response.
-
Native development now uses the live vault’s real organization and write contracts.
bun run tauri devopens the production-selected vault through the same revision, locking, containment, and secure/locked gates as the installed app, including vault settings, model choices, portable Main, and named views. Window-only debug state remains isolated, and location changes plus live delivery tests stay disabled in development. -
Update checks are now explicit. Rotli contacts the signed updater feed only when the user chooses Check for updates in Settings; launch, window visibility, and background timers remain offline.
-
Breve remote briefs fail closed behind the current vault policy. Each model spawn rebuilds its macOS sandbox denials for secure, tainted, locked, derived, and Git files. The knowledge-bearing Codex fallback was removed because its sandbox could not express the same per-file read boundary.
-
Vault is now the consistent product vocabulary. Current contracts call the user-owned folder a vault and describe Rotli’s metadata/projection layer separately; legacy
memexfilenames and APIs remain unchanged for compatibility.
Fixed
-
A new vault now opens as a real empty workspace. Its welcome and mini tutorial are transient UI, so Rotli does not create a throwaway tutorial note or probe an empty note id. Naming the first note creates it through the normal vault workflow. Chat, board, and rich-file tabs also keep a bounded three-item warm cache, reducing WebKit rebuild stalls while preserving independent chat drafts and multiple simultaneously open chats.
-
Chat setup controls are more compact and stable. The optional title’s Enter hint now lives inside the title field, and the model chooser groups Local, Claude Code, Codex, and Antigravity behind a provider rail with search, family marks, keyboard navigation, and a bounded scrolling result list.
-
Onboarding card shortcuts work before the cards have focus. Arrow and visible number keys now move from the selected card on every choice step, while editors and other controls retain their keys. Vault activation also names the exact folder action, and app setup proceeds directly to that real picker instead of stopping on a misleading passive “choose where notes live” screen.
-
Chat image attachments survive reload without trusting the webview. File picks and drops are copied atomically into the initiating registered vault, transcripts keep portable
storage:links, unsupported or mislabeled bytes fail before import, and asynchronous artifact creation stays pinned to that vault even if the user changes the active sidebar context mid-run. -
Switching tabs no longer erases an unsent chat draft. Titles, message text, and image attachments are owned by the initiating tab, and an async first save can no longer bind its result to a different active tab.
-
Native chat writes and external changes now refresh immediately. A newly created chat note is readable before the watcher round trip, and watcher delivery also refreshes chat folders plus the other filesystem-backed projections so installed and development windows converge on the same vault state.
-
Chat detail controls no longer collide visually. Selected provider art keeps its native silhouette without a second tile, and the final reply’s copy controls share a footer with the Rotli mark instead of overlapping it.
-
Generated Word visuals no longer reserve an empty-looking lead page. The DOCX and local editor now agree on inline drawing metadata and frame size, and the image follows the document introduction with preserved aspect ratio.
-
Generated chat images no longer become broken Markdown links. Tool observations provide the exact
storage:source, same-run note creation repairs a shortened generated basename, and successful generation refreshes the asset index immediately. -
Concurrent edits no longer overwrite newer note, board, document, sheet, CSV, generic-file, or saved-chat bytes. Reads carry exact content revisions; stale writes fail as conflicts and keep the local editor buffer available.
-
Quit and every in-app relaunch now wait for all windows to save. A failed or timed-out Markdown, board, document, sheet, settings, or projection flush cancels exit/restart and surfaces the failure instead of claiming success.
-
External renames and deletes no longer discard a dirty Markdown draft. An unresolvable old locator retains its in-memory buffer and reports the conflict.
-
Native file/folder IPC no longer accepts arbitrary absolute paths from the webview. Imports and root changes consume short-lived exact native-picker or drag grants and reject home, credential, Keychain, and application-state roots.
-
Root and chat identity fail closed under collisions. Duplicate or malformed root ids cannot replace an existing route; saved-chat creates refuse an existing slug, updates require a revision, and secure taint is one-way in the same locked write window.
-
Headless CLI/MCP results no longer disclose secure structure indirectly. Main/views and metrics are remote-policy-filtered, status omits absolute root paths, and queued opens require an agent-visible item.
-
Round trips preserve more conventional-file data. Excalidraw retains unknown scene and element fields; DOCX retains unsupported XML/package content or refuses an unsafe advanced edit; XLSX refuses packages containing known advanced OOXML features that the current editor would silently drop.
-
Context menus restore focus without retaining a cleared React event. Closing sidebar, vault, and new-item menus no longer raises an asynchronous
currentTargeterror when their trigger has been rerendered. -
Document-editor styling no longer leaks into Rotli dialogs. Opening a Word pane keeps chat artifact menus and other application popovers in the active Rotli environment instead of forcing the editor’s white-paper palette.
-
Concurrent organization can no longer silently erase newer structure or metadata. Main, named views, chat folders, raw frontmatter, note metadata, Librarian writes, CLI, and MCP now share exact revisions and cross-process filesystem locks. Named-view rollback never replaces a newer note edit.
-
Breve runtime upgrades are staged and recoverable. Rotli frozen-installs immutable code and dependencies beside the mutable managed home, activates them with an atomic directory swap, and restores the prior complete runtime after a failed install or interrupted swap.
[0.80.0] - 2026-08-08
Added
- Quick Note and Quick capture can target separate vaults. General settings now offers an independent destination for each global capture entry point, while preserving Quick Note’s current local-folder option. Explicit vault choices require write access and never silently fall back to another vault.
- The Librarian now explains its filing system where you use it. Its re-openable guide maps intake, Library folders, reference-only views, Archive, Trash, assets, and chats; it also explains the one-file rationale and links directly to Librarian and Security settings.
- Long notes now have a quick way home. A compact arrow appears at the bottom-right after scrolling and returns the Markdown pane to the top.
Changed
- Chat now explains when a Notes view is filtering it. The Chat sidebar names the inherited view and offers one click back to Main and all chats; clicking its existing All chats row now clears the view too.
- Raw vaults no longer strand every new note in Librarian intake. When the
Librarian is off, new ordinary notes land directly in the vault’s
wiki/note lane. Existing files are not moved; secure notes keep their protected home and the rest of the vault structure is unchanged. - Chat model icons now scan at one size. Gemma and OpenAI marks are optically normalized to the same compact sidebar footprint as Claude, Gemini, and Qwen, with a design-system guard covering future additions.
- Background tree saves now feel immediate. The Main/named-view header no
longer flashes
Saving…orSavedafter ordinary organization; failures still surface inline instead of disappearing. - Held-Command hints now read cleanly on the active control. Home, Chat, and New chat show complete Command-inclusive chords that can be pressed directly while the overlay is open; active hints no longer disappear into an accent-on-accent block.
- The onboarding character now lives on the page, not inside a card. Each setup state brings it in with one brief gesture that respects reduced motion.
- Showing file metadata now reveals it immediately. Turning metadata on returns the focused Markdown pane to the banner at the top of the note.
Fixed
- Saved chats stay visible in the Chat sidebar. Selecting an empty or legacy named view no longer turns a non-empty chat list into a blank menu; views with assigned chats still narrow normally.
- Boards can be archived or trashed again. Their menus no longer mislabel
them as read-only files, and items in the System browser can be dragged onto
the Trash row using the same guarded lifecycle as
⌘Delete. - Double-clicking a photo keeps it rendered. The second click now preserves the selected image instead of exposing its Markdown source.
[0.79.0] - 2026-08-07
Added
- Choose where globe-enabled web research goes. DuckDuckGo remains the free, no-account default; Brave Search API is now an optional bring-your-own-key provider whose credential stays in the macOS Keychain. The new Connections settings section names the direct network destination and never reveals a saved key.
- Local answers now read evidence before making current claims. A bounded research tool searches once, reads the top public pages, supplies numbered sources, and validates citations. Missing, conflicting, malicious, or unavailable evidence now steers the model toward uncertainty instead of a confident answer from memory.
- First run now feels like part of the app. The character accompanies every
setup screen with short state-based motion, numbered choices keep their number
beside the label, arrow keys select cards, and the live
⌘Entershortcut sits inside the Continue button it activates. - Bring an existing Markdown vault. rotli inventories Obsidian, ZenNotes, and ordinary Markdown folders without writing, then offers opening in place or importing into an empty destination. Nested folders seed one Main reference tree; note content is neither copied into a database nor rewritten.
Changed
- Local web research now follows an evidence-first reasoning order. Gemma carries a bounded private checkpoint from source inventory through exact fact extraction, reconciliation, citation mapping, and answer-or-abstain. Citation cleanup and date/time/timezone pairing checks catch unsupported combinations without adding an unconditional model call. Explicit source routing keeps unanchored public specifications, trials, transactions, benchmarks, and missions out of personal-note search. If a weak local model still chooses a note search for an unmistakably public question, Rotli corrects it locally without executing the note search or automatically sending a web request.
- Web-search failures are no longer disguised as empty results. DuckDuckGo now distinguishes no results, connection/timeout/HTTP failures, challenges, and changed markup; Brave distinguishes missing or rejected keys, quota/rate limits, network failures, and malformed responses. Rotli never silently retries through a different provider.
- Skipping setup no longer chooses a notes location. It applies the calm
Paper/Charcoal system defaults and continues to an explicit Create or Open
Vault screen. Fresh installs no longer silently create
~/Documents/rotli.
Fixed
- New items stay in the Main folder you chose. Clicking or keyboard-opening a Main folder now makes it the creation target, so choosing an Excalidraw board (or another item type) no longer drops the new item at Main’s root.
- Boards created in a named-view folder stay in that view. The new-item chooser now retains the active view and its selected folder while preserving the board’s global Main reference.
- Excalidraw boards are named before they exist. Creating a board from the chooser, menu, or hotkey now asks for a name first and writes the final, collision-safe filename directly instead of creating an untitled placeholder.
- Held-Command hints now cover tabs and metadata. Tabs show their real
⌘1–⌘9targets in the shortcut overlay, and⌘⇧Mtoggles the focused note’s file metadata through the shared, rebindable action registry. - Dropped photos land where you point. Markdown now captures the exact drop position before importing a photo, so import time, scrolling, or a moved caret cannot redirect the image link elsewhere in the note.
- Photos stay inside Markdown lists. Dropping a photo onto an empty bullet, numbered item, or task now fills that list item instead of leaving a blank marker and inserting the image outside the list.
- Slash commands work inside Markdown lists. Type
/after a bullet, number, or task marker to open the usual command menu. The marker stays put, and multiline inserts remain indented inside that item. - Selecting a whole note keeps its photos visible. Select All and other selections that fully cover an image now leave the rendered photo selected instead of replacing it with raw Markdown text.
- Arrow keys select photos instead of exposing image syntax. Moving into a rendered standalone or list photo now outlines it as an object, matching a click, while an existing caret in image source remains editable.
[0.78.0] - 2026-08-06
Added
- A window you have put away stops animating. rotli lives in the menu bar, so its window spends most of its life out of sight; every animation now parks itself while the window is hidden and resumes when you come back. The relative “updated” time in the editor stops ticking too, and refreshes the moment the window returns — fresher on sight than before.
- The website is ready for search and link previews. Its production build now publishes canonical and Open Graph metadata, a sitemap, robots guidance, and a useful not-found page.
Changed
- Chat rows now show the model’s real mark. OpenAI, Claude, Gemini, Gemma, and Qwen use their recognizable artwork instead of invented letter badges; unknown local models and hybrid presets retain honest text fallbacks.
- The website download button cannot get ahead of a release. It now opens the latest signed release that actually exists instead of constructing a DMG URL from a version that might not have been published yet.
- Upgraded the interface engine to React 19. No behavior changes — this keeps rotli on a supported release line so future editor and board work is not blocked. The React Compiler stays off.
[0.77.0] - 2026-08-05
Changed
- A chat row shows its model, not a chat icon. Every row in Chat was wearing a little speech bubble that told you what you already knew. That slot now carries a small vendor mark for the model answering — so you can see at a glance which chats are on Claude, GPT, Gemini, or your own Mac.
Fixed
- One highlight per open chat. A chat that was working (or unread) appeared twice — once in the lane at the top, once in its real place — and both copies lit up as selected. The lanes are notifications, not locations, so only the row in the chat’s real home is highlighted now.
[0.76.0] - 2026-08-04
Added
- Have replies read aloud. Turn on Settings → AI → Voice and every answer gets a speaker button; press it again to stop. The voice runs entirely on your Mac — nothing is sent anywhere — and it’s prepared the first time you use it, so nothing is downloaded unless you ask for it. Long answers start speaking right away instead of waiting for the whole reply, and code blocks are skipped rather than read out character by character. Seven voices to choose from.
- Fold a section down to its heading. Press ⌥⌘K anywhere inside a section
and it collapses to its title, leaving a small
⋯you can click to bring it back — so a long note can be read as an outline. Folding a heading takes its sub-sections with it and stops cleanly at the next heading of the same level, and the fold survives switching between the beautified and raw views. ####and deeper are headings now. Markdown allows six levels; rotli only recognized three, so a fourth-level heading rendered as a plain paragraph. All six are recognized and styled (deeper levels read as quiet emphasis rather than shrinking away).- A parent task shows how far its subtasks have got. Indent checkboxes under
another one and the parent picks up a quiet
2/4— turning green when they’re all done. It counts only the boxes directly beneath it, so the number always matches what you can see, and it is never written into your file: your markdown stays exactly what you typed. - A task can be in progress, not just done or not. Write
- [/]and rotli draws the box half-filled — started work stops looking identical to work you haven’t touched. It still shows on the Tasks surface, because started isn’t finished. In Settings → General → Checkboxes you can make a click walk through it too: once for in progress, again for done. Typing[/]yourself works either way.
[0.75.0] - 2026-08-04
Fixed
- Dropping an image on a chat attaches it. It used to land in your vault and never reach the chat. Dropped images now attach to the chat under the cursor — and they’re saved into your assets on the way in, so they stay referenceable instead of vanishing when the message is sent.
- You can send an image with no words. “What is this?” needed typed text before the send button would do anything.
Added
- Every connected model can see your images — Claude, GPT and Gemini alike. Each one gets there differently under the hood, and the extra access each needs is granted only for a message that actually carries an image: an ordinary text conversation keeps exactly the locked-down setup it always had. Whether a local model can see images stays a property of that model, read from your AI store — so a text-only local model is never asked to look at something it can’t.
- An attached image is part of the message. Each attachment shows a numbered
preview above the composer and appears in the sent message as
[Image #1], so you can talk about it afterwards — “what’s in image 2?” — and the conversation keeps a record that it was there. - See what a Breve routine actually does. Each routine now has a Workflow toggle that lays out the real pipeline it runs — the schedule and its head-start, the sandbox, the model and its self-heal fallback, the render, audio and preview steps, the hold until delivery time, and every delivery lane. Lanes you’ve switched off still appear, greyed, so you can see what isn’t running as easily as what is. It’s read-only in this pass and derived from the real scripts rather than stored, so nothing about your routines changed.
[0.74.0] - 2026-08-04
Fixed
-
You can see which chat is working, at the top of the list. A chat that’s answering now floats into a Working lane above everything — folders included — so you never hunt for it. The working dot was also invisible on the chat you were actually looking at: a selected row fills with the accent color, and the dot was that same color. It now flips to the contrasting ink, like every other marker on a selected row.
-
Boards can be deleted again. Deleting a board failed with “note not found”, naming a file sitting right there in your sidebar — boards are tracked by their file path while notes are tracked by an internal id, and the delete path only knew how to look up notes. Since deleting is a move to Trash, the same gap silently broke moving and archiving a board too. Boards now move as plain files — their contents are never rewritten — and restoring one from Trash puts it back exactly where it came from.
Added
- Hold ⌘ and the shortcuts appear right on the buttons. Instead of a panel you have to read and translate back to the screen, each shortcut now shows as a small badge pinned to the control it actually drives — so you can see it and go straight there. How the hold behaves is yours: Settings → Hotkeys → Hold ⌘ offers badges on the controls (the new default), the original grouped list, or nothing at all.
- One key flips between Home and Chat (⌃`). ⌃1 and ⌃2 still jump straight to either front, and all three are rebindable like every other shortcut.
Changed
- A new chat opens ready to be named. The title field takes the caret the moment a new chat opens, so you can type its name straight away — ⏎ still skips to the message box (and your first message names the chat if you’d rather not). A chat opened into a split pane doesn’t steal your focus.
Added
- Generate an image right inside a note. Type
/in any note and pick Generate image: choose which model draws it, describe the picture, and the finished image is saved into your vault and dropped into the note where you were typing. The model list only ever shows engines you’re actually signed into — GPT Image through Codex, Nano Banana through Gemini — so there’s nothing to pick that can’t run. If neither is connected, it says so up front instead of failing partway. Generated note images live together instorage/images/; chat-generated images keep their own per-chat home as before.
[0.73.0] - 2026-08-03
Fixed
- A sent chat appears in the sidebar instantly. Your message is saved the moment you press Send — so a brand-new chat shows up in the left bar right away, at the top, already pulsing while it thinks, and an existing chat jumps to the top on send instead of on reply. Your own message is also never lost anymore if the model fails mid-answer. (A new chat’s tab also claims its identity at send time, closing a race where a reply could land on the wrong tab.)
- The Gemini (Antigravity) lane no longer dies on “agy returned nothing… auto-denied”. The cloud model occasionally reached for the CLI’s own tools, which headless mode silently denies — aborting the whole turn. rotli now spawns that lane in an empty scratch directory, tells the model plainly it has no native tools, and when the abort signature still appears, retries once with a hard override. Permissions stay denied — nothing was loosened.
[0.72.0] - 2026-08-03
Added
- The chat sidebar now works like a real multi-chat cockpit. Fire off several chats and switch freely: a chat that’s answering breathes a small dot on its row, a reply that lands while you’re elsewhere flips it to an unread dot and collects it in a new Unread lane at the top — so you always know which chat to click. Chats order by response recency (newest reply on top, inside folders too), and leaving a chat no longer cancels a send that was waiting in line — it finishes and lights up its row.
- Pin chat folders. A folder’s right-click menu can pin it above the rest.
- Every chat row shows its model. The model a chat runs on sits quietly at the row’s right edge.
- Views reach the chat area. Organize chats by work vs personal: assign a chat to a named view from its row menu, switch views to see only that view’s chats, and a chat started while a view is active joins it automatically.
- Replies show real tables and diagrams. A markdown table in an answer
renders as an actual table, and a
mermaidflowchart renders as the drawn diagram — right in the chat. The assistant is encouraged to use both (in replies and in the notes it writes) when they genuinely clarify. - The assistant can draw on a board. Ask for a visual diagram and the model can turn a flowchart into a real, fully editable Excalidraw board saved with your boards and opened on screen. Under the hood the model writes Mermaid — which even small on-device models do reliably — and rotli converts it locally; nothing leaves the Mac, and chats carrying secure-note content can’t put their prose on a board.
Changed
- Reordering chats inside a folder by hand is retired — response recency now owns the order (pinned chats still float first). Dragging a chat onto a folder still files it there.
Fixed
- Bold text in chat replies no longer shouts.
**bold**in an assistant reply was falling to the font’s heaviest cut, which read far too thick against a dark thread. Chat bold now uses the same semibold emphasis the rest of the app speaks. - Each vault’s chats keep their own settings. A chat’s model pick, web-search globe, and column width were remembered by chat name alone — so two vaults with a same-named chat silently shared one setting. They’re now remembered per vault, existing settings migrate automatically, and renaming a chat carries all three along instead of losing them. Isolation is locked in by tests on both the TypeScript and Rust sides: chats and notes never travel between vaults.
[0.71.0] - 2026-08-03
Fixed
- Numbered checklists finally look like checklists. A step written as
1. [ ] Generate the new keyused to show the[ ]as literal text — only dash checkboxes rendered. Numbered steps now get a real checkbox next to their number, clicking it checks the step off, Enter continues the list with the next number and an empty box, and open numbered steps show up in Tasks like every other checkbox. - Notes the Librarian has filed stay editable. In a memex, a note the
Librarian moved out of the intake area into its curated home (say
wiki/engineering/) hit “this location is read-only” on every save — the editor kept your text and retried forever, but the save could never land. The wholewiki/tree is now a writable surface for your own edits: filing a note organizes it, it doesn’t freeze it. The brain’s memory lanes, control files, and read-only vault settings are as protected as before, and the Librarian still owns its metadata keys exclusively.
[0.70.0] - 2026-08-03
Changed
- On-device chat answers as it thinks — words appear as they’re written instead of all at once. The local model used to hold its whole reply until it was finished, so you’d watch a spinner and then get the answer in one drop. Now the answer streams in as it’s generated, and Stop ends it mid-sentence while keeping whatever had already arrived. Only the on-device model streams; the connected lanes and the background organizer are unchanged.
[0.69.0] - 2026-08-03
Changed
- The app opens a touch quicker, and it stays smooth while it works. A board’s drawing engine no longer loads its styles at startup, so a session that never opens a board starts leaner; a bit of first-launch housekeeping now waits until after the window is on screen. On-device chat starts answering sooner — it no longer double-checks which notes it’s allowed to read before building its map of your notes. And a few background chores (listing notes, searching, gathering tasks) moved off the main thread, so the window keeps responding while they run, and drag-selecting in the file browser stays smooth.
[0.68.0] - 2026-08-03
Changed
- On-device chat can reach the web when it should. Ask it something that needs current information — the latest on a topic, who signed a letter, what just shipped — and it now recognizes its notes may be out of date instead of answering from them as if they were current. With the globe on, it searches and reads the web and answers from what it found, with sources. With the globe off, it tells you it’d need the web and leaves turning it on to you. It reasons about this rather than watching for a magic word, so it also catches questions that don’t say “latest” out loud.
- On-device chat shows its work. A multi-step answer now narrates what it’s
doing — “searching your notes”, “reading
”, “searching the web” — so a long answer feels like progress instead of a frozen pause. - The rotli mark stays crisp when it’s small. The quokka in the titlebar, tabs, and chat no longer smears into a blur at small sizes — same drawing, lines that hold their weight.
[0.67.0] - 2026-08-03
Changed
- One highlight for “you’re here.” The Home/Chat switcher’s active segment and the current item in the Main view menu now wear the same accent highlight as a selected note — one active-item language across the sidebar instead of three near-misses.
[0.66.0] - 2026-08-02
Changed
- The build toolchain reached current. Rotli moved to Vite 8, which now carries its Rust bundler (Rolldown) natively — the same fast builds, minus a temporary alias and a deprecated plugin. Nothing about the app changes: the bundle ships a touch smaller and one known security advisory drops out of the build’s dependencies.
[0.65.0] - 2026-08-01
Added
- Search got fast and smart. Finding a note no longer scans every note on every keystroke — Rotli now keeps a real search index, so search stays quick as your vault grows from hundreds of notes to thousands. It also got smarter: typing two words finds the notes that have both, a half-typed word matches as you go, a small typo still lands the note you meant, and wrapping a phrase in “quotes” finds those exact words in order. The index is Rotli’s own private cache next to your notes — it’s rebuilt from your Markdown whenever it’s needed and never something you have to think about; your files stay the only thing that’s real. Secure notes are handled exactly as before: they show up in your own searches and never in anything a cloud model can see.
Changed
- The sidebar has a Home and a Chat, and you pick one. The stacked “Chat”
and “Notes” sections are gone. A small two-segment switcher now sits under
your vault name: Home is your notes — All notes, Captures, Tasks and the
Main tree you arrange yourself — and Chat is your chats, folders and all.
Whichever you pick gets the whole sidebar and just scrolls, so you no longer
fold one away to see the other, and Chat no longer stops at five recent
conversations with a “+7 more” — every chat is right there. Rotli reopens on
the side you were last using.
⌃1goes Home,⌃2goes to Chat, and New chat moved to⌃⇧2; every one of those is still yours to rebind. Opening something always brings the right side forward — click a note and you land in Home, open a chat and you land in Chat — so “show me where this is” never points at a panel you can’t see. Settings lost its “Chats in the sidebar” count, which no longer had anything to limit. - The System area folds away. Library, Assets, Archive and Trash now sit under a heading you can click shut when you want a quieter sidebar; the Files · Librarian · Settings row at the very bottom stays put, under both Home and Chat. Pressing Collapse all twice still folds everything — the second press now tucks the System area away instead of the old sections.
- The build got about nine times faster. Rotli’s bundler moved to rolldown and its typechecker to the Go-native TypeScript compiler, so a production build drops from ~10.4s to ~1.2s and a full typecheck from ~3.5s to ~0.8s. Nothing about the app changes — the same bundle ships, slightly smaller — but every fix now reaches you sooner. Babel and esbuild left the toolchain entirely, and a new dead-weight gate keeps unused code and undeclared dependencies from accumulating.
Fixed
- Breve’s mail reader and Signal listener got two real crashes removed. Asking Breve to read an email by an id its mailbox no longer holds threw instead of saying it couldn’t find it, and one path through the Signal message handler could trip over an attachment it assumed was there. Both surfaced when the runtime’s untyped edges were given real types.
- Chat no longer searches your notes for nothing. When a local model phrased a tool argument as a nested object instead of plain text, the search ran on the literal text “[object Object]” and quietly came back empty. It now says what went wrong so the model can correct itself.
[0.64.0] - 2026-08-01
Changed
-
A dead-end search hands the model a map instead. When the on-device model searches a word no note contains (“runtime”), the miss now returns the vault’s complete area list — each with its leading note title — and tells the model to search the area that would hold the answer. In live runs the model then finds “Preferences” and answers with the truth; when it still can’t, it says “I couldn’t find that in your notes” — the answer-every-part-from-a-read rule now forbids a guess dressed as a fact.
-
Chat can reach your identity notes now. The parts of a vault that hold who you are —
identity/,personality/, your dailyhistory/,MAP.md, andinbox.md— used to be invisible to every model, so “what do I do for work?” had no reachable answer. Chat can now find and read them the same careful way it finds anything else: search it, open the one note that matters. It is still retrieval, not stuffing — nothing preloads your vault. They stay out of the Notes sidebar, and no AI can write to them. -
Secure and locked finally mean two different things. Secure hides a note from cloud models — completely, no setting, no exception. Models running on your own Mac can now read secure notes by default, which is the point of running one: nothing it reads leaves the machine. Any single note can still opt out from its menu, and the whole vault can from Settings → Security. Locked is not about hiding. A locked note is one no AI may edit — cloud or on-device, in chat or by the Librarian. Everyone can read it; nobody but you can change it. The note menu and the Security pane now say exactly that.
-
Secure notes a chat has read still can’t leak sideways: a chat that has seen one can only write into notes that are themselves secure, and its transcript can never be handed to a cloud model afterwards.
[0.63.0] - 2026-08-01
Added
-
Panes fit, whatever the size. A pane is a hard box now: shrink the window, drag a divider to the edge, stack two chats — chrome compresses and scrolls instead of bleeding into the pane below. Panes keep a usable minimum height (derived from what a chat actually needs, not a guess), re-fit live as the window changes, chat titles make room for their buttons instead of sliding under them, and empty states scale the quokka down before clipping the words.
-
Every chat keeps its own model. Two chats side by side can now run two different models at once: the chip under the composer shows that chat’s model, sends from that chat use it, and it stays with the chat across relaunches. Picking a model no longer reaches into every other open chat. A brand-new chat still starts on the last model you picked, so nothing changes if you only ever use one.
-
On-device chats wait their turn instead of bogging down your Mac. Run as many local chats as you like — before each reply starts, rotli checks how much memory this Mac actually has free right now and how big that model is. If there’s room it just goes; if there isn’t, the message says “queued — not enough compute headroom right now” and waits, with a Prioritize button to run it next. Stopping or leaving a queued message takes it back out of the line. There’s no fixed limit on how many chats you can have open — a roomy Mac runs several at once, a smaller one runs them one after another. Claude, Codex and Gemini are unaffected.
Fixed
-
The note’s chat button offers your chats again. Clicking it lists every chat on the note plus “New chat” — it used to fall into the same chat every time because each message quietly re-pointed the chat at a freshly minted notes file (that’s also where those duplicate “chat about …” notes came from; no more of those). Conversation notes now land in the note you chatted from, in their own managed section, instead of spawning orphans.
-
“List the people in my vault” answers with your people. The on-device model used to open the
people/README — a note that explains how the folder is organized and names nobody — and read its list of links out loud, so a project could end up in a list of your family. Three things changed: notes filed under a folder you name (“people”, “projects”) now turn up in the model’s search instead of only notes that spell that word out; the area’s generated index — the note that actually lists everyone — is marked as such and offered first; and a note’slinks:line is labelled as pointers, not an answer. Asked for a roster, rotli now reads the roster. -
The model picker opens fully in a split. In a stacked layout the list used to open upward past the top of the window and come back clipped — a menu starting mid-air over the conversation. It now measures the room its chip actually has, flips below when there’s more space there, and scrolls inside itself instead of running off-screen.
-
Tab indents the line again. Pressing Tab on a line that wasn’t already a list item pushed two invisible spaces in at the cursor instead of moving the line, so writing the text first and then reaching for Tab left the line where it was — and a
-typed next stranded at the end (test -, rendered literally, no bullet). Tab now shifts the whole line one level, cursor and all, exactly like Shift-Tab has always brought it back. Tab inside a fenced code block still types a soft tab at the cursor, and Tab with text selected indents the line instead of replacing what you selected.
Changed
- Nested bullets read as a clean ladder. Each level now shifts the whole item by one even step, and the bullet, number, or checkbox sits in a narrower column right beside its words instead of drifting off to the left. Wrapped lines in a task line up under the task’s text. No vertical indent lines — nesting is spacing, nothing drawn.
[0.62.0] - 2026-07-31
Changed
- Half the size. The installed app went from 40 MB to 20 MB. The Chinese handwriting font for boards is no longer bundled (CJK board text falls back to a system font), the binary sheds its debug symbols, and ~6 MB of hyphenation dictionaries and interface translations no code path could ever load are gone.
- Typing got lighter. Keystrokes no longer re-render the editor shell, re-scan the whole document, or wake the tab strip and note lists — the background sync tick that re-derived everything four times a second while you typed is quiet now. Most noticeable in long notes and multi-pane layouts.
- Chat stays smooth in long threads. Settled messages no longer re-render while you type your next one, and the sidebar’s chat list no longer reads entire transcripts just to show titles.
- The Librarian reports instantly. Activity status, the queue count, and the secure-note badge update on real events instead of a once-a-minute check.
- The whole toolchain moved to oxc (oxlint + oxfmt + the tsc lane split out): the full lint gate dropped from ~12s to ~2s, formatting from ~2s to ~50ms. Dev-facing, but it guards every release.
Fixed
- Quit can’t outrun a board save anymore. A pending board write now holds the quit handshake until its bytes land, and closed boards no longer pile up quit work for the app’s lifetime.
- A failed Librarian cycle shows its error — the status strip could previously miss it in a race and show nothing.
- Releases can’t embed release artifacts. The updater feed used to stage inside the folder that gets baked into the binary; a stale build could have shipped 55 MB of the previous release inside the app.
[0.61.0] - 2026-07-31
Added
- Your own routines. Routines → “Add a routine…” creates a custom brief — Breve researches your prompt on schedule, with the same care as the morning brief — or a reminder that delivers your words at a chosen time. Custom briefs land in the Briefs list under their own name. The three daily briefs also take extra instructions now, and every routine that speaks for you shows an Instructions editor.
- The brief playbook, in your hands. Routines → “Brief instructions” shows the exact system prompt every brief follows — edit it and the next brief uses your version (no restart), or reset to the shipped default.
- Breve in every vault. A fresh vault offers “Start Breve in this vault”: one click brings your delivery setup and routines along (shared defaults), and each vault’s briefs, watchlist, and routines stay its own.
- Briefs speak. Each brief with a spoken version shows an inline audio player in the reader.
Fixed
- Creating or switching vaults no longer freezes the app. The folder picker and the whole vault lane moved off the main thread, and the Librarian’s boot sweep waits out the first paint.
- Empty Trash empties everything — trashed files and boards (not just notes) now delete; “Emptied 0 of 35” is gone.
- The Librarian’s “Open the note” opens the note (area overviews used to land on an empty Untitled tab), and the same fix reaches the Briefs reader’s “Open in Notes”.
- Collapse-all is two-stage: first press folds open folders (chat folders included — and they stay folded across relaunches now), second press folds the sections themselves. Its tooltip no longer clips at the sidebar edge.
- Tasks reads cleanly: wrapped checkboxes show their full text, bold and
code marks render instead of leaking
**, and every group header shows which note it is — glyph, count, and a click-through. - Theme polish: the warm accent no longer leaks into Paper/Charcoal icons, and the Librarian’s settings button sits clear of its divider.
[0.60.0] - 2026-07-31
Changed
- “Run now” is a real audit. Beyond new and changed notes, it now checks every note for missing metadata — a note “processed once” whose summary, tags, or links never landed gets caught and filled in. Nothing hides.
- The log shows its work. Click any history row for a real diff — the old value struck out, the new one beneath it, moves shown as from → to — with the note itself one link away.
- The Librarian’s settings control is a labeled button, not a bare gear.
[0.59.0] - 2026-07-31
Changed
- Onboarding shows its keyboard. Every pickable card wears its number, and a quiet hint above the footer says what the keys do — 1–9 pick, arrows move, ⏎ selects (again to continue), ⌘⏎ selects and continues.
[0.58.0] - 2026-07-31
Added
- You can always see the Librarian working. The sidebar’s Librarian button pulses a quiet dot whenever anything runs — a scheduled pass or the background adopter — with the current note’s title in its tooltip. Inside the Librarian, a standing status strip shows the trust level, the organizing model, and the last pass, with settings one gear-click away.
- Onboarding by keyboard. Numbers pick a card, arrows move between them, Enter selects (Enter again continues), ⌘⏎ selects and continues.
Changed
- Organize truly works in the background now. Metadata suggestions no longer pile up in the Waiting lane at Organize — leftovers apply themselves through the same guarded, journaled, undoable lane the Approve buttons use. The one thing that always waits for you, at every trust level: filing a note the Librarian isn’t sure about.
- “Run now” lights up the moment you click it, and explains itself when it has to wait for an in-flight chat.
[0.57.0] - 2026-07-31
Added
- Approve everything at once. The Librarian’s Waiting lane gains “Approve all N” and an armed “Dismiss all…” — the whole backlog in one deliberate click, with stale rows skipped safely and reported honestly.
Fixed
- “Run now” always answers. An explicit run that finds nothing new says so (“Nothing new to organize — everything is already filed”) instead of silently closing — it read as a dead button.
- One action at a time in the Librarian: while a batch runs, every other mutating button waits its turn.
[0.56.0] - 2026-07-31
Added
- rotli:// links — a clickable path into the app. When Claude, Codex, or
any agent manages a note through the rotli CLI/MCP, the result now carries a
deepLink(rotli://open?id=…) beside the disk path. Click it anywhere — terminal, chat, another app — and rotli surfaces with that note open. Links are ids only, validated hard (traversal, absolute paths, and hostile shapes are ignored), and clicking one can never touch anything outside your vault. Works cold too: a click launches the app and still lands on the note. - ⌥F — find from anywhere. The ⌥-letter family’s search twin: one global chord summons rotli with the ⌘K palette already open. Rebindable like every chord.
- Rows resize like columns. Drag a row’s bottom edge in a rendered table to set its height (a minimum — content still grows it); double-click the edge to reset. Persisted per table on this Mac, the .md never changes.
Changed
- Table menus wear standard icons. Alignment is the familiar horizontal-lines trio (left/center/right) instead of arrow glyphs, and the Move actions carry arrow+lines icons — instantly readable.
- Wide tables scroll, not squeeze. A table wider than the editor column now scrolls horizontally inside its own container instead of crushing its columns below readability.
[0.55.0] - 2026-07-31
Added
- Watch the Librarian work — and stop it. “Run now” opens a live band that narrates each note the organizer is looking at (“Looking at “X” — 3 of 12“, titles only, never content), with a Stop button that finishes the current note and hands control back. A last-run summary line replaces the mystery.
- Meet the Librarian. A first-visit explainer says exactly what it may touch (a note’s location and its metadata — never its words), what it always skips (locked notes, secure notes, your Main), how each trust level differs, and that secrets are found by on-device patterns, not AI. Re-open it anytime from the ? in the Librarian’s header.
- Empty Trash. The Trash browser gains an armed two-step Empty Trash; items land in the macOS Trash, so “forever” stays honest. The sidebar Trash row wears an alert badge when it piles up.
- Journal hygiene. Clear logs older than 30 days, or all history (armed two-step — cleared entries take their Undo with them). Pending suggestions always survive a clear.
Changed
- The Librarian reads like a page, not a wall. The mascot emoji is gone; suggestions group per note (“«X» — 4 suggestions: links · tags · summary · area”) with Approve all / Dismiss all; history folds into days with the long tail behind View all.
- You always know what’s waiting. The sidebar’s Librarian button wears a red badge when a sensitive-data decision needs you, or a tinted count of suggestions awaiting approval — Suggest mode is never a silent queue.
- Tidy vs Organize, finally clear. The captions now state their one real difference: Organize also keeps each area’s overview page fresh by itself.
Fixed
- Journal entries and
filed_bystamps now name the model that actually did the organizing — a Claude-organized run used to be recorded as the local model.
[0.54.0] - 2026-07-30
Added
- A note owns many chats now. The editor’s chat chip opens a picker — every chat on the note, newest work first, plus “New chat about this note”; ⌥-click (or ⌘⇧C) skips the picker and continues the latest. Additional chats get their own slugs and “· 2”-style titles, so a second conversation never lands in (or overwrites) the first. The note context menu grows “New chat about this note”, and both verbs are rebindable actions.
- Read your briefs inside Breve. The Briefs page now opens with the latest brief rendered right there — older/newer stepping, kind + date + reading time, and a finite close: “That’s the whole brief — distilled from your topics. Next: …”. Library rows load into the same reader; leaving Breve is only the explicit “Open in Notes”.
- ROADMAP.md — the planned-features home: the email Inbox front’s return, mobile and tablet apps, and the handwriting-to-text notebook experience.
Changed
- Chat messages read like a premium chat surface. The per-message “rotli” label is gone — replies are plain text; hovering a message reveals its options (Copy, with a ✓ beat); the quokka mark appears once at the thread’s live edge, ahead of a streaming reply or resting after the last one.
- Breve reorganized, reading-first. The rail is Briefs · Routines · Watchlist · Settings — Models and Configure merged into one Settings home, which also hosts the legacy-migration steps. The watchlist arrives as calm folded groups (search auto-expands; your open groups survive saves).
- The Inbox placeholder left the sidebar. rotli shows two fronts — Chat ·
Notes — until the mail integration is real (see ROADMAP.md). Capture,
wiki/_inbox, and the Librarian’s intake are untouched.
Fixed
- The onboarding hint for ⌥C said captures land in “Inbox” — they land in Captures, and the hint says so now.
- Two settings forms editing Breve config at once can no longer clobber each other’s saves or silently drop an unsaved draft on navigation.
[0.53.0] - 2026-07-30
Added
- The chat can edit your notes now. A new
update_notetool lets the model rewrite an existing note when you ask — “clean up my summary on this note” becomes a real edit, not an apology. It rides the same write lane the editor uses (frontmatter and metadata preserved), may only touch notes it is allowed to READ (secure gates enforced in Rust, unchanged), and a chat carrying secure content can only edit notes that are themselves secure. If the note’s tab is open, it refreshes live — and your own unsaved edits in that tab always win. - A landing light for pane focus. When focus moves between split panes — by hotkey or click — the arriving pane flashes a brief accent outline that fades, so your eye lands where your keyboard did.
[0.52.0] - 2026-07-30
Changed
- The Library selects like a Finder. Folder tiles join the selection grammar items always had: ⌘-click gathers several, ⇧-click ranges across the folder band, and the empty-space marquee sweeps folders and items alike — in Icons and List views (Columns keeps its click-opens-the-next-column law). ⌘-click also mixes folders and items in one selection.
- The Library stops showing its plumbing. The
_templatesandCapturestiles are gone from the Library grid — both looked like broken empty folders, and neither is a browsable area:_templatesis the vault’s contract-owned template lane (the organizer deliberately skips it), andCaptureswas the_inboxstaging lane, whose notes already live in the Captures front (sidebar + board). Nothing was deleted from disk — they were never rotli’s to delete.
[0.51.0] - 2026-07-30
Added
- Chats can be reorganized inside their folders. Drag a chat onto another chat in a folder to place it exactly there (the same drop-line grammar as Main); dropping on the folder row still files it at the end. The manual order lives in the same rebuildable sidecar as the folders themselves.
- Every reply can be stopped. The send button becomes a Stop while rotli is working — connected CLI models are killed for real, the local model’s in-flight reply is discarded — and your prompt returns to the composer intact, ready to edit and resend.
Changed
- Naming a chat is optional by design. The title field says so — press ⏎ on it empty and you drop straight into the message box; the chat names itself from your first message.
- New chats land where you’d look for them. A chat started while you’re in a foldered chat files itself into that same folder; the loose list now sorts most-recent-first (pinned still float), so a fresh chat is always at the top, never buried at the bottom.
- Working looks alive. The static “thinking…” now ambles through a warm little vocabulary — reading the shelves…, connecting dots…, brewing an answer… — beside the pulsing dots, and real tool statuses still take over when something concrete is happening.
- The local model answers like it means it. The Gemma prompt now carries an explicit answer contract — lead with the facts themselves, never “that’s documented in the family/ subfolder”, with a BAD/GOOD example it can imitate — and asks for Markdown structure (bulleted lists, bold names), so replies come back direct and formatted instead of vague and flat.
- One sidebar row grammar. A consistency audit of the whole left menu: every first-level row now starts at the same left inset across Inbox, Chat, and Notes (chat and inbox rows sat 6px deeper for no reason); chat-section icons match the tree’s sizes; chat folder rows drop their bold (the chevron and folder glyph carry folder-ness, exactly like Main’s folders) and share the tree’s chevron column; the open chat now wears the same solid accent pill as the open note (one active-item state, replacing the lighter wash); and the “+N more” / connect-a-memex rows hover with the shared wash like every other interactive row. Verified in all four environments — Warm Light, Warm Dark, Paper, Charcoal — with every semantic token the sidebar consumes resolving in each.
[0.50.0] - 2026-07-30
Changed
- Chat folders read as folders. The Chat section’s folder rows now carry the Notes tree’s disclosure grammar — a rotating chevron beside the folder glyph, with chats indented one clear step beneath — and you can drag a chat onto a folder to file it (same pointer-drag as the Main tree: the row dims, the folder tints, drop assigns).
- Chat rows match note rows. The right-click menu gains Open in new tab,
Open to the right, and Show in Finder (revealing the real
chats/<slug>.mdon disk), alongside the existing Pin, Rename, Move to folder, Copy file path, Archive, and Delete. - The active tab lost its blue top line. The 2px accent edge that marked the focused pane’s active tab is gone — the tab already reads active by merging into its editor.
Fixed
- The chat’s note button opens only the note. With “open beside the chat” set, clicking the note icon used to split the pane with a duplicate of the chat and then add the note next to it; the split now carves the new pane with the note alone.
[0.49.0] - 2026-07-30
Fixed
- A note that can’t save says so. A failed note write (read-only volume, permissions, disk full) now surfaces an inline error above the text — “This note isn’t saving” — keeps your words in the buffer, and retries on its own every few seconds (quit still attempts one final write). Before, every failure except a deleted note was silently swallowed and the only hint was a muted dot. (Perf audit 2026-07-30, correctness #1.)
- Sheet embeds joined the quit-flush lane. A ```sheet fence edited inside a note now registers its unsaved cells with the same hide/quit flush the full sheet editor uses, parks them across scroll-away remounts, resumes a parked session instead of showing stale rows, and surfaces write failures inline. And while the sheet’s own tab is open anywhere, the embed goes view-only — two live savers can no longer overwrite each other’s cells. (Correctness #2.)
- Main can’t lose an arrangement quietly.
.rotli/main.jsonwrites now carry the same latest-wins sequence guard named views always had, and the sidebar’s Main header shows Saving…/Saved — with an inline error if the write fails. (Correctness #3.) - Settings survive a transient write failure. The debounced settings/ viewstate writer only marks a payload written once it lands, so a failed write retries instead of silently reverting your theme, keybindings, and panes at next launch. (Correctness #4.)
- Captures multi-select no longer resets mid-flight. Selecting several capture cards survives unrelated background changes (Main edits, Quick access changes) — the reveal-and-select effect now fires once per reveal instead of on every list refresh. (Correctness #5.)
Changed
-
The window stops freezing for background work. The commands that used to run on the main thread — web fetch/search for agent tools (up to 20s each), document conversion, memex validation, Breve’s email/Signal delivery tests, the model-download progress walk, and the system profile — now run on worker threads, so the app keeps painting while they work (every security guard unchanged and in place). The corpus walk behind every note list is memoized against a change generation — your own writes and external file changes (via the watcher) refresh it, everything else answers from cache — and search and the Tasks list reuse that one parse instead of re-reading every note twice. A chat’s first token no longer waits on ~350 serial per-note permission probes: one batched Rust check (same enforcement, same secure detector) answers for the whole hit list. And the 750ms
rotli openmailbox poll (~115k IPC calls/day) is gone — Rust forwards the CLI’s activation as arotli:open-requestevent instead. -
Startup got ~35% lighter and typing got dramatically cheaper. The quokka illustrations (~450 KB, 29% of startup JS) now load on demand — same inline line-art, same theme tinting, just fetched the moment a quokka moment appears; katex is bundled once instead of twice (−260 KB and no more double-load); and Settings, Breve, and Onboarding code-split off the entry chunk. Typing in a note no longer refetches the whole notes universe every 400ms — the editor patches its own save straight into the caches (full refreshes still run for create/move/trash/external changes, and the Tasks list re-derives only when checkbox lines actually change). Launch hydration reads its files in parallel, batched file drops and multi-archive/trash run their independent writes together (with exact per-item failure reporting), and a dead-code sweep dropped ~470 lines of orphaned CSS, four unused exports, and an unused native devDependency.
-
The Breve watchlist reads before it edits. Topics now render as compact scannable rows — name, source domain, one-line guidance — under their group headers instead of a page of always-open forms; clicking a row (or its explicit Edit) expands one in-place editor with a Done to fold it back. Every group header carries its own “+ Add topic” button, so adding to a group no longer requires hunting; “Add group” stays in the sticky manager bar beside Save. Validation moved off the page banner and onto the offending row (“Name this topic, or remove it.”), with a compact fix-the-marked-rows hint next to the disabled Save and a needs-attention note on collapsed groups hiding invalid rows. Same watchlist Markdown contract, same capabilities — presentation only.
[0.48.0] - 2026-07-30
Added
- Code blocks read like an IDE. Fenced code with a language tag (
ts,json,python,rust, ```bash and twenty-some more, aliases included) renders with real syntax colors — keywords, strings, comments, numbers, functions, and types each in their own voice, tuned per theme by riding the accent palette. Languages load lazily so notes stay fast, an unknown language stays plain (never wrongly colored), and the markdown source is untouched. - Table columns resize by drag. Grab any column boundary in a rendered Markdown table and drag; widths persist per table on this Mac (the .md never changes) and a double-click on a boundary returns the table to automatic layout.
- Reviews now teach the tooling. A tracked, sub-second pre-commit hook
(staged-file Prettier + conflict-marker guard; enable with
git config core.hooksPath .githooks) plus a standing rule in CONTRIBUTING: when a review flags a class of issue, the same PR lands a mechanical guard for that class.
Fixed
- Images load in notes from every location — and repair themselves.
Relative and
storage:image links resolved only against the primary corpus, so notes living in a connected brain showed empty broken boxes — they now resolve against the note’s own root. And a link that stops resolving is classified, not abandoned: a MOVED image heals the link to its new home, an ARCHIVED image still renders (the link stays untouched so a restore heals it naturally), an image in the TRASH says “photo deleted — in the Trash”, and only a truly gone file reads “not found”. - Images follow their note. Trashing or archiving a note takes its images to the same place — unless another note also uses them (the check is conservative: any doubt keeps the file put). A General setting, on by default; restoring a file from Trash or Archive returns it to its original path, so the note’s link works again immediately.
- Settings reads as one column. Every control now holds a single shared width — the four themes sit in one row, segmented choices are compact controls instead of full-width bars, and the App icon area no longer floats against a stretched segment above it.
[0.47.0] - 2026-07-30
Added
- Chat folders. Right-click a chat → Move to folder to group the Chat section into collapsible folders — organization is virtual (chats never move on disk), folders rename and delete from their own menu, and a renamed chat keeps its folder.
- ⌘N speaks digits. The chooser tab is a centered grid with a number on every card — ⌘N then 1 opens a chat, 2 a Markdown note, 3 a Document, and so on. Chat joined the chooser as a first-class card.
Fixed
- Local replies no longer freeze the app. The model transport ran on the main thread, so every on-device generation beachballed the whole window and even your just-sent message painted late — it now runs on a worker, keeping the app responsive (and send instant) while a model thinks.
- Local models search smarter and follow up properly. The agent prompts
now teach 1-3-keyword searches (the engine matches exact substrings, so
whole-question queries found nothing) and that a follow-up asking for
specifics requires re-reading the source note — proven against a live
whole-vault evaluation (
scripts/eval-vault-sweep.ts, a reusable harness that reads the real vault only through the workspace CLI’s security boundary). The full findings and the retrieval roadmap live indocs/design/local-model-retrieval-notes.md. - Clicking All chats no longer leaves the previously open chat highlighted beneath it — one selection at a time.
[0.46.1] - 2026-07-29
Fixed
- Local-model chat reads your notes before answering about them. Asking the
on-device model things like “who are the people in my vault?” used to get a
wrong list parroted from note titles, search snippets, and
links:stems (e.g. a project offered as a person) — the model never opened the note, and when it did, the body was cut at 2,000 characters with no warning. The agent prompts now carry an explicit search → read → answer workflow, teach that[[wikilinks]]and frontmatter are references/metadata rather than content, the 128k local family (Gemma 3) reads up to 6,000 characters per note with a visible[…truncated]marker when a note is longer, and final answers are steered to concrete facts instead of note titles. Verified with live evals against the local MLX server (scripts/eval-local-chat.ts).
[0.46.0] - 2026-07-29
Added
- The chat composer grows with you — up to seven lines while you type, then it scrolls inside, so long messages stay visible instead of hiding behind one cramped line.
- A real thinking indicator — three quietly pulsing dots ahead of the status line while a model works (still, for reduced-motion users).
- Chat models can create and open notes. Ask for a note in chat and the model writes it through the same intake lane as the CLI (staging/Inbox, the organizer files it later) and can open any note on screen in a tab.
- Copy file path on a chat’s right-click menu — the chat is a real
chats/<slug>.mdfile, and now the menu says so.
Changed
- Text selection wears your primary color — a translucent wash of the theme accent instead of the fixed peach tint, in the editor and everywhere.
- The chat’s attached note is real conversation notes now. The model that answers also keeps a “Conversation notes” section — decisions, facts, action items, open questions — like a colleague taking notes, replacing the old speaker-labeled transcript, its visible HTML markers, and the stray “> chat:” blockquote (old notes migrate on their next update; without a usable model the section falls back to a topics digest).
Security
- Secure-note content can no longer reach a remote model through chat
history. When a local model reads a secure note during a chat turn, the
chat is permanently marked
secureContext— remote and routed models leave its picker, web search locks off, sends to non-local models refuse, its transcript is excluded from remote models’ chat-memory retrieval, and no unlabeled memory note is written from it. - A secure-context chat writes secure notes. When chat carries secure-note
content, any note the model creates is stamped
secure: true— the model can’t launder secure prose into an open note (Greptile P1, PR #4). - Boards joined the remote egress gate. Connected agents (CLI/MCP) can no longer read, list, or rewrite a board whose scene carries secret-shaped content — the boards mirror of the note lane’s rule.
- Breve’s keychain unlock password left the process table. Unlocks and
secret writes now ride
security -iover stdin instead of argv, and the image-generation sandbox explicitly denies the Breve keychain file. Uninstallfor a local model only trashes inside the models store. A corrupt or hostile registry path can no longer point the delete at an arbitrary folder.- The memex read lane refuses symlink escapes — spine reads resolve through the same containment as every corpus lane instead of a string check, and real read errors are no longer reported as empty files.
Fixed
-
Unreadable notes fail closed. A note that can’t be read (permissions, invalid UTF-8) now refuses blank-discard and body saves instead of being treated as empty — previously it could be trashed or have its frontmatter (including
secure: true) silently regenerated. The brain journal and corpus.gitignoregained the same protection against wholesale rewrite. -
Visual mermaid shapes are visible again. A generic button reset was outranking the shape styling, leaving nodes as bare labels until selected; shapes now render their fill and border in every theme, and connections stop at each shape’s border — arrowheads land on the shape instead of hiding under the label.
[0.45.0] - 2026-07-29
Added
- Mermaid grew a camera — everywhere. The diagram in your note pans and zooms in place (scroll zooms, drag pans, double-click fits, a still click opens the workspace), and the Visual editor gained the same camera: scroll to zoom at the cursor, drag empty canvas to pan, − % + Fit controls, with node dragging staying exact at every zoom level.
- Converting to Excalidraw lands beside the note — same Main folder, same named view — and offers Convert & replace in note, swapping the mermaid fence for the new board embedded right there.
- Mermaid diagram is a New… item, next to Board: a note born with the starter flowchart.
- ⌘N opens a blank chooser tab — pick Markdown / Document / Sheet / Board / Mermaid and the tab becomes it. ⌘⇧T is New board now; reopen-closed-tab moved to ⌘⌥T (everything stays rebindable).
Fixed
- Files added to a Main folder that a named view mirrors now show in that view too.
- Embedded boards (and sheets/documents) remember their resized height across edits and restarts.
- Protection toggles in the row menu (Lock from the AI, Mark secure) wear a lock in the gutter — the star belongs to Quick access alone.
[0.44.0] - 2026-07-29
Added
- Quick Look. Press Space on anything selected in the System browser — or pick Preview from any row menu — for a modal peek without opening the full surface: images, PDFs, audio, video, text and CSV heads, and a readable note render. Formats without a faithful cheap preview show an honest metadata card. Open escalates to the real surface; Esc closes, and focus returns to where you were.
[0.43.0] - 2026-07-28
Added
- Pictures look like pictures. Image assets in the System browser show a real thumbnail instead of a generic glyph — in the icon grid and in the new Gallery view: Finder’s fourth view, a big preview over a filmstrip (←/→ walk it, ⏎ opens). The view switcher now wears the standard Finder icons, with the words in tooltips.
- Duplicate. The row menu’s new copy verb: a full copy titled “title copy” that opens on create. Placement routes like every new note — in place for a plain folder, Brain staging for a curated memex folder — and failures say so instead of mislaying the copy. (“Move to…” is retired: it listed Library areas no matter which view you were in.)
Changed
- The path bar moved home. The System browser’s crumb trail now sits at the bottom, Finder-style — every segment navigates, and the selected item is the leaf. Right-clicking empty space offers New folder and Sort by Name / Kind / Date modified / Date created (pick again to flip direction).
- The Library tells the whole truth. It now lists the files and boards living inside wiki folders (brief PDFs, images, canvases) — not just notes, which read as broken next to Assets.
- The sidebar footer. Files · Librarian · Settings share one quiet row (the Activity row renamed — it’s the Librarian’s journal). The New-board header icon folded into the New… menu, the header keeps to one row with the vault name shrinking to “…” first, and header tooltips can no longer clip off a narrow sidebar.
[0.42.0] - 2026-07-28
Added
- Bare links are links. A plain
https://…typed into a note now renders as a real link — ⌘-click opens it in the browser, same as[text](https://example.com/docs/url)links. The chat surface opens them on a plain click. - Close every tab. The last tab’s × is no longer hidden: close it and the pane rests with the quokka and three quiet ways back in (⌘N new note · ⌘K search · ⌘⇧T reopen). ⌘⇧T restores exactly what you closed.
Changed
- The sidebar breathes. Section chevrons (Inbox · Chat · Notes) moved to the row’s right edge and the Main tree lost its wasted first indent step — icons and labels start flush left. The pinned System zone is smaller and quieter: compact muted rows that warm up on hover.
- One selection grammar. The redundant accent bar beside active rows is gone everywhere (menus, sidebar rows, chat rows) — the tinted background alone marks the active item.
- Wikilinks tell the truth.
[[links]]survive renames (the old title and filename ride along as aliases) and keep working for archived notes; a link whose note was deleted — or never existed — now renders dimmed with a dashed underline and says so, instead of silently doing nothing.[[target|shown]],[[target#heading]],[[target.md]], and path-style targets all resolve.
Fixed
- ⌘K arrows work with the mouse parked over the list. Scrolling the selection used to fire synthetic hover events that snapped it back under the cursor — arrow keys read as dead. Selection now only follows real pointer movement.
- Assets no longer claims “Nothing here” beside a real count. The
Assets/Archive/Trash browsers compared destination names against on-disk
memex lane paths (
Storagevsstorage/…), so the listing always came up empty. Paths are now read through the destination’s namespace.
[0.41.1] - 2026-07-28
Changed
- Browsing doesn’t pile up tabs. A plain click opens a note (or board, or file) into one reusable preview tab — shown in quiet italics — and the next click reuses it. Click the same item again, or start editing, and the tab stays for good. ⌘-click and ⌘T still open real tabs, exactly as before.
Fixed
- CI-only e2e flake: select-all in the editor now uses the platform modifier (⌘A was a dead key inside CodeMirror on Linux runners).
[0.41.0] - 2026-07-28
Changed
- Main rows gather. ⌘-click Main rows to select several, then one drag moves the whole selection into a folder — a plain click still just opens.
- Capture cards read at a glance. The card shows up to six lines of the capture (they’re one-off quick notes — the card is often all you need); click still selects, double-click still opens, and “Make a note” graduates it.
- The left menu settles. Main is no longer collapsible — its header is purely the view switcher; the Recent row is gone (All notes already sorts by recency); System is pinned at the sidebar’s bottom, always visible, never collapsing; and a quiet Files button under it opens the vault folder in Finder. Active System rows drop the wash and bar — the open surface on the right already says it.
- The System browser selects like Finder. ⌘-click toggles, ⇧-click ranges, and dragging on empty space rubber-bands a selection; ⌘⌫ moves the selection to Trash. The Kind column now shows real file types (PDF, PNG image, Spreadsheet…), echoed on grid tiles.
- A third view: Columns. The Finder column view — each column lists one folder, clicking a folder opens the next column, double-click opens the item.
- Pick your primary color. The active state, folder tint, and selection wash can follow you across themes: Default (each theme’s own), Blue, Green, Violet, Rose, or Amber — tuned per light/dark scheme, chosen in onboarding’s theme step or Settings → Appearance. Charcoal with a blue primary is now a thing.
[0.40.0] - 2026-07-28
Fixed
- Bullet indenting handles foreign notes. Notes written by external editors or AI tools indent lists with tabs — those bullets rendered as raw text, Shift-Tab did nothing, and Tab just typed spaces. Tab-indented bullets, tasks, numbered items, and quotes now render at their proper depth, and Tab/Shift-Tab quietly normalize the line to rotli’s two-space levels as part of the gesture.
Changed
-
Splits and tabs forgive. Closing a pane merges its tabs into the neighbor instead of discarding your working set; ⌘⇧T reopens the last closed tab at its old slot; ⌃⇧Tab cycles backward; and the tab menu gained “Split right/down with this tab”.
-
“Open to the right” in the note menu splits with the target — “this note beside that one” is one gesture now instead of split-open-close-the-duplicate.
-
Panes read clearer: unfocused panes’ tab strips mute slightly, dividers show their grab line on hover and double-click to even out (drag is also smoother — one resize per frame), and ⌘⌥-arrow focus now finds any pane that actually shares an edge.
-
The left menu speaks one grammar: a System/smart row whose surface is open carries the same accent wash + bar as an open chat; selection no longer bolds (labels stop re-truncating); zero counts hide instead of badging “0” and the Notes header stops duplicating the All-notes count; Activity gets its own pulse icon (Recent keeps the clock); the text “▾” carets became real glyphs; drag-drop indicator lines and the added-folder × no longer shift the layout; the full Quick-access star stays visible and explains itself when clicked; empty states share one voice; and Main folders answer the keyboard “m” menu (rename and friends) with proper aria-expanded state.
-
Boards stop rewriting themselves. Opening, panning, zooming, or selecting on a board no longer touches the file — only durable content (elements, images, canvas background, grid) persists, and an unchanged scene never writes. In a vault that’s a git repo this ends the phantom diffs, and serialization now runs once per save instead of on every pointer move — the big-board stutter is gone.
-
The canvas owns its keys. ⌘D used to duplicate a shape and split the pane; ⌘0 reset canvas zoom and toggled the sidebar; ⌘=/⌘− were dead over a board. Inside a board those chords now belong to Excalidraw — zoom where you are. The vendor’s own theme toggle is gone too; the titlebar sun is the one theme owner.
-
Boards look like rotli. The canvas accent, islands, and default background now follow the app’s theme family in all four environments — no more stock-violet island floating in a warm app.
-
Embedded boards can’t fight their tab. While a board’s own tab is open anywhere, its note embed goes view-only (two live editors used to silently overwrite each other’s strokes). Embed save failures now show the same warning strip the full canvas has, and pending board saves register with the quit-flush handshake — ⌘Q inside the save window can no longer drop your last strokes.
-
Board rename failures say why (read-only vault, name collision) in the sidebar’s error lane instead of silently snapping back.
-
Manual filing is back. The System fold had quietly removed every by-hand move: right-click a note → Move to… now refiles it into a Library area (through the Librarian’s journaled, undoable lane when it’s on) or any plain folder — which also un-strands raw vaults, where captures had no way to leave the intake folder at all.
-
“New folder” works again. The toolbar button had been a silent no-op — and the last folder-creation UI — since the System fold. The Library browser now has its own New folder here (the toolbar button routes to it while a browser is open; elsewhere it starts a Main folder). Vault rules still apply: a memex’s curated tree politely refuses, plain vaults create anywhere.
-
A note can no longer be born in Assets. Browsing Assets then ⌘N used to drop a markdown note inside the managed
storage/lane; creation now routes to intake/Inbox like every other non-home selection. -
Activity opens beside your work, not over it — it was the one surface that replaced the tab you were on instead of appending.
-
The sidebar is fully keyboard-walkable again: Captures and Activity joined the j/k order (the cursor used to teleport past them), and pinned Main notes no longer desync the keyboard order from the visual one.
-
⌃⇧Tab cycles tabs backward, and the tab menu gained Close tabs to the right.
-
Shrinking the window respects the pane floors — the sidebar now auto-collapses on resize when splits need the room (it only checked at split time before).
-
Main’s empty-state copy no longer references the removed ⊕ affordance, and ~700 lines of unreachable sidebar code left behind by the System fold are gone (the dead thicket that hid these regressions).
[0.39.0] - 2026-07-27
Fixed
- The current view is visible again. The view switcher’s active row used a tint that vanished on the dark themes — it now carries a small accent bar and an accent-mixed wash that reads at a glance in all four environments (still no checkmark gutter; labels stay flush).
- Collapse-all no longer reopens folded sections. The toolbar’s collapse-all folds the trees, but it used to reset the Chat/Notes/Main section fold states back to open as a side effect. Sections now stay exactly as you left them.
Changed
- The sync answer, in words. SUPPORT.md now documents “your folder, your sync”: recommended setups (iCloud Drive · git · any folder-sync tool), the one-app-per-vault caution, and the honest mobile story — plain files any editor can read.
- The System browser is now a real Finder. You’re in one folder and see only its direct contents — subfolders as folders, notes as items. Double-click a folder to enter it, climb back with the breadcrumb (or ‹), single-click to select, double-click to open: the exact conventions your hands already know. Folders is the icon grid; List is the columned list (Name · Date Modified · Kind) with disclosure triangles and sortable columns. Search still flattens across the whole root, “Show in Library” now lands you inside the note’s folder, and empty folders render as real tiles.
[0.38.0] - 2026-07-27
Changed
- The Library browser shows empty folders. A folder with zero notes is still a real folder (Finder truth) — it now renders with a 0 count instead of vanishing. Searching still hides match-less folders.
- “Show in Library” lands on the note’s exact folder. The note menu and the editor’s location chip now open the Library browser with the note’s folder expanded, the row marked with the app’s one active state, and the list scrolled to it — not just the browser root.
- Raw vaults are visible in Settings → Location. The notes-folder row and
each linked library card show the same quiet
rawbadge the vault switcher uses when a vault runs without the Librarian.
Fixed
- Editor paper-cut sweep — a focused QA pass over tables, navigation,
indentation, and checkboxes (16 defects confirmed by adversarial review;
all 16 fixed):
- A pipe typed into a table cell can no longer eat its neighbor. Cell
pipes now serialize as GFM
\|, pasted tables with escaped pipes parse correctly, and serialization pads short rows but never truncates long ones — the three paths that silently deleted cell content are closed. - Prose +
---is not a table. A delimiter row must match the header’s cell count (the GFM rule), so “Alpha | Beta” above a---divider stays text instead of being swallowed into a table widget that rewrote the---. - Tab is never stuck in a ragged table row — missing cells are skipped and Tab past the last real cell grows the table, as always.
- Fenced code is grammar-free. Space after
[], Enter after a dash line, and Tab inside a ``` fence no longer rewrite your code with list markers or task boxes. - Numbered lists renumber on Enter. Inserting an item mid-list bumps every following sibling (1. 2. 2. is gone); nested items ride along.
- Format-bar toggles respect indentation. Bullet/numbered/checklist on a Tab-nested line toggles its own marker instead of stacking a second one at column 0 — and over a multi-line selection they now toggle every spanned line and keep the selection.
- The task shorthand is more forgiving:
- []+Space upgrades an existing bullet, and a pasted tab indent normalizes to spaces so the task renders. - Enter at the very start of an empty list item inserts a line above instead of silently eating the marker.
- Back/Forward forgets discarded notes — closing an untouched new note removes it from the trail, so Forward can’t reopen a note that no longer exists; filing a note to the Brain now retargets trail entries the same way it retargets open tabs (board and chat renames follow suit, and a file moved to Trash leaves the trail).
- Back/Forward remembers boards, chats, and files — every content surface now enters the trail, so Back from a board returns to the board’s predecessor instead of skipping to the last note. Replay also reuses the surface’s open tab in any pane — no more duplicate tabs spawning in whichever pane happens to hold focus.
- A pipe typed into a table cell can no longer eat its neighbor. Cell
pipes now serialize as GFM
[0.37.0] - 2026-07-26
Changed
- System opens like a Finder, not a dropdown. The Destinations section is now System (Library · Assets · Archive · Trash · Activity), and each row opens a real file browser on the right instead of an inline tree: a search box on top, a Folders ⇄ List toggle, real folder structure (never synthetic groupings), and rows that open, right-click, and drag into Main like every other list. “Add a folder…” moved to Settings → Location where vault management lives.
- Main collapses. The Main header’s label is now a disclosure — one click folds the whole section. Changing views got its own quiet ▾ beside the name, and a new-note button joined new-folder in the header.
- One header row. The vault switcher and the create toolbar share a single line — less chrome before your notes begin.
- The cursor points, it doesn’t grab. Draggable rows and images show the familiar pointing hand at rest; the open-hand grab only appears mid-drag.
- The left menu got quieter. The vault header sits lighter (regular weight, tighter rhythm) and the always-visible create marks fell to a whisper at rest — present when you reach for them, invisible when you read past them. The vault switcher also grew up: New vault… scaffolds a fresh vault wherever you point it, and raw vaults carry a quiet “· raw” suffix so you always know which vaults the Librarian looks after — Librarian-on stays unmarked, because the default shouldn’t shout.
[0.36.0] - 2026-07-26
Added
-
Meet the Librarian. The AI layer has a name and a face: the quiet on-device helper that files your notes into the Library and fills in their metadata is now the Librarian, with the quokka to match. Settings → Librarian is its home — the switch, the explainer, and how much it may do — and its change log is Librarian Activity. Same behavior, warmer name; nothing about your files or settings changes. A connected vault now reads “Linked library” so it can’t be confused with your own Library.
-
A practice vault, one click from onboarding. Want to try rotli (or walk a friend through it) without touching your real notes? Onboarding’s location step gained “Try a practice vault”: rotli scaffolds a scratch vault, carries your settings over, and keeps your current vault registered — untouched, and one click away in the vault switcher.
-
A vault can now be raw — no AI touches it. Settings → Brain gained a master switch, and onboarding now leads with the promise (“your vault is just a folder”) before asking the one question: a brain (rotli’s AI files and tags your notes, logged and undoable) or a raw vault (just your files, organized by you). Raw means the organizer never runs, nothing files or enriches — enforced independently in the daemon and the write boundary — while security never turns off: secure notes, the secret detector, and repairs work identically in both modes. Flipping the switch never moves or rewrites a file, an untouched vault keeps today’s behavior exactly, and turning the Brain back on resumes gently at Suggest.
[0.35.0] - 2026-07-26
Added
- Tasks — every open checkbox, one view. A new Tasks row beside All notes
gathers every
- [ ]you’ve written across your notes, grouped by note with a live count. Check one off right there — it’s a real edit to the note (the note stays the only truth), re-validated against the exact text so a note edited meanwhile refuses instead of flipping the wrong line. Fenced code is ignored; Archive and Trash never nag. - The sidebar header is a vault switcher. The top of the sidebar names the vault you’re in; one click lists your known vaults (current one highlighted), switches between them — honestly labeled, since switching relaunches — connects another vault, or jumps to Location settings.
Changed
- Storage is now Assets. One system home for every image, video, PDF, and file — same lane on disk, clearer name everywhere it appears (sidebar, Settings, file surfaces, note locations).
- Sidebar create affordances are always visible, and system rows have none. The per-folder new-note/new-folder pair and the Main-header new-folder mark no longer hide until hover — they sit quietly beside the counts at reduced strength. Storage, Archive, Trash, and Secure notes rows drop their create affordances entirely: those are system surfaces, and the toolbar’s New… actions still target them when selected.
[0.34.1] - 2026-07-25
Changed
- Exclusive choice menus mark the current option with a highlight, not a checkmark. The Main view switcher and both “Move to view” submenus (note menu and Main-folder menu) now show the current view as a tinted active row, so sibling rows sit flush left instead of carrying a checkmark indent. Ordinary ✓/★ toggle menus (Pin, Lock, Secure, Star) keep their macOS-style gutter — those are on/off states, not a choice among options. The chat model picker drops its redundant trailing checkmark for the same reason: the highlighted row already is the answer.
[0.34.0] - 2026-07-24
Added
-
Notes that look sensitive now ask you, right in Brain Activity. A non-secure note whose content trips the secret detector shows up as a review row — open it, Make secure (the existing protected move), or say Not sensitive and rotli remembers that answer for that exact content, re-asking only if the note changes in a way the detector can see. Nothing is ever auto-marked from this lane, and the AI keeps refusing to read or move the note while you decide.
-
Settings gained a Security section. What a secure note is, how one is born (quick captures, detection, your own mark), and the fail-closed rules — never sent to remote models, kept out of git, organizer hands-off, on-device access opt-in per note — in plain language, plus where repairs live.
-
Spreadsheets and CSVs gained a Details popover. The sheet header’s Details button shows the file’s canonical location (with one-click copy), size, created/modified stamps, format facts (CSV/TSV delimiter, UTF-8), and every sheet’s dimensions — computed fresh when you open it, stored nowhere. Truncated previews say “2,000+ rows” instead of pretending to be exact.
-
Brain Activity can repair legacy secure notes stuck in intake. A note explicitly marked
secure: truethat still sits physically in Brain intake (wiki/_inbox/) — pre-lane state from an older version, or an external move — could never leave: the organizer correctly refuses to read secure notes, and nothing else moved them. The Activity pane now previews these notes by title and, on one explicit click, Rust re-validates each on disk and completes the protected move intowiki/_secure/(destination.gitignoreentry lands before the move, prose stays byte-identical, the same stable id survives). The repair refuses non-secure targets, symlinks, and read-only corpora, and its journal rows are content-free — ULIDs and lane names only, never a title, summary, body, or tag. Secure organization itself remains unimplemented; the organizer still never reads a secure note.
[0.33.6] - 2026-07-24
Changed
- Sidebar menus are aligned, scrollable, and explicit about data lifecycle.
Ordinary actions no longer carry an empty checkmark indent, long menus keep
their Trash actions reachable, named views say “Remove from
,” and “Move to Trash” is reserved for the durable file operation. Virtual folders can move their nested contents to Trash through a second confirmation, while Copy File Path exposes the native file location beside Show in Finder. - Note filenames are now readable, deterministic title slugs. A note titled
“Strategy master” is stored as
strategy-master.md; same-title siblings usestrategy-master (2).md, and stable ULIDs remain in frontmatter instead of leaking into filenames. Typing a new title or using Rename updates the file, preserves old title/file selectors in human-readablealiases, and lets wikilinks androtli renameresolve exact titles, filenames, aliases, or IDs. Untouched legacy files are not rewritten merely by opening the memex. - Frontmatter now has an explicit record contract for filesystem querying. Identity, human selectors, user organization, and AI enrichment have declared ownership and types; aliases participate in local search while unknown user metadata continues to round-trip.
- Memex v3.8 adds deterministic structured queries. The packaged CLI
accepts expressions such as
area:projects tags:payments updated:>=2026-07-01, and the read-onlyrotli_queryMCP tool exposes the same implicit-AND grammar with inspectable parsed clauses. Rotli applies its secure-content gate before matching and never writes an index or normalizes files during a query. - The title rule now matches the foundation contract exactly. The first H1 wins even when prose or lower-level headings precede it; Rename edits that H1, while deliberately renaming an H1-less legacy note promotes its former title line to H1. Unicode title words remain readable in filename slugs.
- Legacy filename repair is explicit and reviewable. The foundation
repair-v38-filenames.tscommand defaults to a JSON plan showing collisions, aliases, and wikilink effects; Rotli itself still performs only guarded per-note adoption and never bulk-renames during listing or startup.
Fixed
- PDFs, DOCX files, sheets, and other file surfaces now stay visible in the sidebar. The focused file uses the same active-row identity as notes and boards, and opening it expands the folder chain that contains it.
- Editing a long Markdown table cell no longer reshapes the table. The inline editor preserves the rendered column widths and minimum row height, wraps long values, and grows vertically when the edit needs more room.
[0.33.5] - 2026-07-23
Changed
- Markdown tables now edit as tables. Clicking a rendered cell opens one
focused inline editor while the surrounding rows and columns stay rendered;
Tab continues through cells, keyboard focus is visible, and pipe-delimited
source remains available through the explicit
</>escape hatch. - Raw Markdown now has a restrained IDE-like syntax theme. Rotli’s active accent marks source punctuation while a contrast-safe blue carries headings and emphasis; fenced code, links, quotes, and table structure remain legible across Warm Light, Warm Dark, Paper, and Charcoal. Appearance settings can switch the same grammar to a user-selected monochrome palette.
- PDFs can become editable local DOCX copies. A compact action in the PDF header extracts embedded text offline, preserves page boundaries, creates a new managed DOCX, opens it for editing, and leaves the PDF untouched. Image-only/scanned PDFs refuse an empty conversion and ask for OCR; complex layout still carries an explicit review warning.
Fixed
- DOCX files with Word lists open in the editor again. Rotli now maps bullets and numbering to Univer’s registered presets instead of invalid lowercase aliases that crashed list-heavy documents during mount.
[0.33.4] - 2026-07-23
Added
- Mermaid diagrams now have a real working surface. Click a rendered
diagram to open a keyboard-safe View/Visual/Code workspace with drag-to-pan,
wheel/button/keyboard zoom, fit, loading/empty/parse-error states, explicit
source apply, and an unapplied-change guard. Visual mode builds supported
flowcharts with draggable shapes, labels, direction, node colors, and labeled
arrow variants while keeping readable Mermaid as source truth; advanced
syntax refuses lossy visual rewriting.
/Mermaidinserts a valid starter. Desktop users can optionally convert an applied diagram into a separate, independently editable Excalidraw board while the Markdown fence stays intact. - The packaged CLI can rename a note and its file directly.
rotli rename "CURRENT TITLE OR ID" "NEW TITLE"resolves one exact note, refuses ambiguous title matches, preserves Markdown heading syntax and managed frontmatter, and routes the physical filename change through the guarded corpus write path.
Changed
- Moving between related notes no longer depends on the sidebar. Visible wikilinks open with a normal click, the note date now shares a compact labeled back/forward trail, and tree rows omit a parent folder name repeated at the start of a child title without rewriting the underlying Markdown.
- Agent and model context is explicitly untrusted and bounded. Model Mapping 0 now emits escaped structured JSON instead of prompt-shaped Markdown; note and tool-result framing resists role/delimiter injection, and copied private prose is refused before an enabled web/image tool can send it off-device. MCP requests and outputs are size-capped, returned note/board content is labeled untrusted data, and replacement/removal/move tools advertise their destructive behavior so clients can require approval.
Fixed
- Full-screen rename, render expansion, and Mermaid workspace backdrops now use the same flat semantic scrim as Command Palette and WhichKey, with static and four-environment browser regressions preventing pale glow effects from returning.
- Corrupt or oversized Excalidraw files are preserved instead of becoming an autosavable blank canvas. GUI, CLI, MCP, and Rust writes share bounded scene validation for file size, elements, embedded files, strings, coordinates, nesting, and semantic action count. The full canvas offers reveal, retry, and a separately confirmed blank-board repair.
Security
- Corpus reads and mutations now resolve every existing path component with no-follow metadata and canonical registered-root containment. Symlinked note, board, office-file, folder, move, sidecar, and atomic-temp parents fail closed instead of redirecting work outside the memex.
- Markdown SVG fences now rebuild a strict allowlisted SVG tree. Event handlers,
scripts,
foreignObject, external resources, unsafe URL schemes, inline styles, and unexpected namespaces never enter the live document; production CSP remains a second layer. - The secure-organizer proposal was revised before implementation: secure
creation remains in
wiki/_secure, legacy intake files require an explicit protected-lane repair, and only a registered on-device model may produce final allowlisted metadata when both the default-off global setting and the note’slocal_ai_allowed: truepermission are present. No secure-derived envelope may reach a remote filer.
[0.33.3] - 2026-07-21
Changed
- Rotli’s product surfaces are flat across all four environments. Tooltips, dialogs, popovers, cards, drag previews, canvas/render overlays, and selection states no longer use glowing backdrops, blur, decorative filters, or drop shadows. Hierarchy now comes from semantic surfaces, borders, outlines, and state layers; component CSS can no longer bypass those roles for fixed brand colors.
Added
-
Main now opens focused named views without becoming another store. Main remains the global reference tree; uniquely named views add their own virtual folders and subset arrangement through a compact header switcher.
⌘T, new items, and new folders follow the active view, while right-click menus move notes, boards, files, and folders between views without removing their Main reference. Markdown membership is synchronized as managedview_tagmetadata; boards/binaries stay frontmatter-free. The JSON CLI, stdio MCP, workspace metrics, live external-write refresh, compatibility refusal, unit, Rust, and browser regressions cover the same workflow. -
Rotli now has one agent-safe headless workspace surface. The packaged app binary provides a structured JSON CLI and a local stdio MCP server for Claude, Codex, and scripts: list/search/read/create/update/move notes, manage Main and folders, create and semantically edit Excalidraw boards, and open an item in Rotli. New memex notes still land in intake and appear in Main immediately; secure/secret-shaped notes are omitted, locked notes refuse external-agent writes, and every edit requires a fresh revision to prevent stale overwrites. A grouped
agentsurface now prints copy-ready Claude/Codex setup, validates the configured root read-only, and runs an isolated end-to-end self-test. Note results explicitly declare Markdown/frontmatter semantics and provide readable document and agent-visible workspace metrics.
Fixed
- The workspace MCP server now negotiates only a protocol version it actually implements. An initialize request carrying an unknown future version no longer gets that value echoed back as a false compatibility claim; Rotli returns its supported protocol and lets the client accept it or disconnect.
- Production builds and regression emails are clean and actionable. Vite’s generic chunk warning is replaced by tested startup/lazy bundle budgets, and only JSXGraph’s exact unreachable compiler warning is suppressed while the interpreter-only CSP guard remains enforced. The advisory RustSec job now has permission to publish its report and cannot fail the workflow merely because tracked upstream advisories remain.
Security
- The Rust lockfile now uses patched
anyhow1.0.103 andquick-xml0.41.0 (throughplist1.10.0). The remaining RustSec unsoundness is explicitly scoped to Tauri’s Linux-only GTK3 dependency graph; current JS and Rust transitive findings and their removal paths are refreshed indocs/development/security.md.
[0.33.2] - 2026-07-20
Added
- Changes now carry their proof with them. Project-level
ARCHITECTURE.md,DESIGN.md, andSYNTAX.mdcontracts define system, interaction, naming, and formatting rules. The documentation guard now proves the contributor/Claude/ CARL graph, release/CI proof chains, and CARL domain catalog stay aligned; structure checks enforce folder and Rust module naming as well as filenames. - AI evals and Main creation have named regression gates. The regression chain runs deterministic offline model, prompt, tool-loop, retrieval, and memory-workflow evals, while Playwright proves Command-T from a Main note opens a new tab and exposes the intake-backed note in Main immediately.
Fixed
- New notes now work from Main and the Brain view.
⌘T, New Note, and the tab-strip plus route Markdown notes through Brain intake (wiki/_inbox) even when the virtual Brain header or a curated Brain area was the last selection. Opening a note from Main also makes its Main folder the active creation context, so a stale physical-folder selection can no longer steal the next note. The new file is referenced in Main immediately; the organizer still waits for its quiet window before filing the same file into a Brain area.
[0.33.1] - 2026-07-18
Security
- The webview can no longer be served arbitrary
$HOMEfiles. The asset protocol’s static scope is now empty; the only grants are the runtime per-corpus-root allows, soasset:URLs resolve inside registered memex roots and nowhere else (decision 1, docs/development/security.md). Deliberate consequence: a note embedding an image by ABSOLUTE path outside your memex (e.g.) no longer renders — move the file into the memex (drag it in) to show it. - The agy image job is OS-sandboxed. It ran with
--dangerously-skip-permissions; it now runs under asandbox-execprofile that denies$HOMEexcept the chat’s assets dir and the CLI’s own state (ROTLI_IMAGE_SANDBOX=0opts out). Decisions 2/3/5 (safe-fetch rebinding residual, image-attachment scanning, prose-overlap egress) are recorded as deferred/accepted with rationale in docs/development/security.md.
Added
- Drift guards, so the repo reads like one author. Per-tree filename law (src camelCase; scripts/e2e/docs/breve-runtime kebab-case — six breve files renamed to comply), tsconfig strictness parity across the three compilers (with measured, dated divergence entries), orphan-script and orphan-check guards, testing.md command-map completeness, minimal identifier naming-convention linting, CSS kebab-case + functional-color bans, and snake_case IPC command naming — every rule mechanical, all mutation-tested.
[0.33.0] - 2026-07-18
Security
-
New security layer (
check:security) + audit remediations. A mechanical guard now pins the whole egress surface: every ureq / raw-fetch/ network-CLI call site must be declared in a tracked allowlist (scripts/fixtures/egress-allowlist.json), no second HTTP-client crate can enter Cargo.toml, keychain account names may only appear via their named constants, and thetauri.conf.jsonCSP /assetProtocolscope / updater endpoints / granted capabilities are snapshotted so any widening fails the lint. Alongside it, several audit findings are fixed: the chat transport now clamps its destination to registered loopback model servers or the pinned Gemini base (an arbitrary webview-supplied endpoint is refused), the local llama.cpp Bearer never rides to a remote base, the file-read IPC lanes (corpus_file_text/_bytes/open_file) now run the same../-traversal guard as the write lanes, the AIread_filetool applies the secret screen before sending file contents to a remote model, tool results are fenced as untrusted data (never instructions) with framing-keyword neutralization, thegenerate_imageprompt is framed as data to the nested agent,web_fetchgained a URL-length exfil cap, and Breve’s local-model tier now fails closed on a non-loopback endpoint unlessllm.allowRemoteis set. CI gained an advisory dependency-audit lane (bun audit+ rustsec). Threat model, egress map, and the reported-not-fixed list live indocs/development/security.md. -
Chat’s
web_fetchtool is SSRF-hardened (remediation batch 0). Hostname resolution now happens on a dedicated agent whose resolver rejects private, loopback, link-local, and cloud-metadata address ranges — vetting the connected IPs themselves, so DNS rebinding cannot slip past a pre-check. Schemes are http(s)-only, redirects are followed manually (≤ 3 hops, same-host only), and the response cap is one named 2 MB constant. TypeScript (Breve’s safe-fetch) and Rust enforce egress independently and are both held to the same adversarial fixture suite (scripts/fixtures/egress-fixtures.json). DDG search and local-model chat traffic are unchanged.
Added
- New notes are ephemeral until you write. A note you create and close
without typing simply ceases to exist — no “Untitled” clutter in Main, and
nothing lands in the in-app Trash (it goes straight to the OS trash /
.rotli/trashfallback, recoverable but out of sight). Any keystroke, frontmatter edit, or lock/secure toggle makes it permanent. Rust re-verifies blankness before every discard, so content can never be destroyed. The same lane now powers “dismiss an empty note from Main” — which had been silently dead since 2026-07-07 (its emptiness check was unsatisfiable).
Fixed
- Clicking a new Main folder no longer deletes it. Every Main folder row
rendered an always-visible remove-× with note-row-only styling, so it sat
unstyled mid-row — right where a click on the folder lands — and one click
silently rewrote
main.jsonwithout the folder. Removal now lives only in the right-click menu (like note rows), a freshly created folder scrolls into view instead of being appended out of sight below every note, andmain.jsonwrites are refused from the quick/capture webviews (which hold an empty manifest and could have wiped it). - The Main header’s “new folder” button now wears the IDE-style folder-with-plus glyph (same as the toolbar) instead of an anonymous “+”.
Added
- rotli knows your name. Onboarding asks (optionally) what to call you —
editable any time in Settings → General — and chat’s local and connected
models address you by it. The name lives in
.rotli/settings.jsoninside your memex, on this Mac only. - New mechanical guards.
check:secret-parityfails CI the moment the TS/Rust secret-pattern mirrors drift;check:architecturenow walks the vendor seams (exceljs, Excalidraw, Univer, JSZip must stay behind their codec/engine adapters);cargo clippy -D warningsjoins the CI regression lane; andbreve-runtime/gets a strict TypeScript pass. - TS↔Rust parity harness (remediation batch 1). Values shared across the
language boundary — sheet byte cap, convertible document extensions,
keychain service/account literals, CLI binary candidate paths,
endpoint-locality verdicts, memex permission values — now live in named
constants asserted on BOTH sides against one fixture
(
scripts/fixtures/parity.json) by hand-written cargo and bun parity suites;check:parityguards the harness itself in the lint chain. Known drift was reconciled first: the TS endpoint-locality check now requires http(s) like Rust, the sheet editor passes its byte cap explicitly, and the CLI candidate lists are byte-identical. - ESLint joins the lint gate (batch 2): floating/misused promises,
no-explicit-any, and react-hooks correctness onsrc/. Adoption caught a real rules-of-hooks bug (onboarding called a hook inside a callback — fixed).breve-runtime/scripts/was measured and deferred at 75 findings; the rationale is recorded in CONTRIBUTING.md. - A deterministic duplication miner (batch 6,
bun run check:dup): within-language shingling plus rare-literal and lifecycle bundles over TS + Rust, with a committed allowlist and an opt-in cached model judge for triage. Validated one-time against the pre-remediation tree: it rediscovered the pointer-drag and clamp clusters exactly and the rename-input cluster indirectly; the two sub-30-token fragment findings sit below the function-level mining floor by design (the full record is pinned in the miner’s header comment). Never a blocking gate. - The adding-things placement contract (batch 7,
docs/development/adding-things.md): one table for where new surfaces, dialogs, overlays, features, vendor libraries, utilities, Tauri commands, TS↔Rust shared values, Breve runtime code, and CARL domains go — and which check enforces each row. New ROTLI_EDITOR and ROTLI_KEYS CARL domains close the editor/hotkey recall gap;check:docsnow measures CARL coverage mechanically (every top-levelsrc/dir over 2,000 lines needs a mapped domain or a recorded exemption) and verifies every path the contract cites exists;check:code-shapeenforces the surface/dialog naming homes.
Changed
- One spreadsheet library. Read-only sheet viewing and chat file-reads now
run on the same exceljs codec as the editor. The abandoned SheetJS (
xlsx) dependency — CVE-2023-30533, unpatched on npm — is removed and banned bycheck:structure. TSV files now parse into real columns. - Dedupe and re-homing sweep (batch 3). One home each for ext/filename
parsing (
src/lib/fileKind.ts), day-bucketing, clamp, the inline rename input, the editor block menu (now on the shared context-menu host, gaining keyboard nav), Breve’s markdown→text strip (one imported helper inside breve-runtime plus a cross-boundary behavioral fixture,scripts/fixtures/markdown-strip.json), switch knobs, and empty-state CSS. Misplaced modules moved to their owning layers (briefs model →src/routines/, board/chat rename →src/services/). - All four pointer-drag surfaces ride one shared drag session (batch 4,
src/lib/pointerDrag.ts): threshold, ghost lifecycle, Esc/pointer-cancel, click-swallow, and window-listener teardown are implemented once; drop semantics stay in each caller. Migrated one surface per commit (main add-drag, tab drag, board cards, sidebar tree). - Structural seams (batch 5): boards share one session core behind the
canvas surface and the Markdown embed; sheets/boards/noteChat/editor are
now named clean-architecture exemptions, so opt-in-by-file-presence is no
longer a silent state;
MemexPermsis a real Rust enum end-to-end instead of stringly-typed compares. - Formatting decisions recorded (batch 8, decision-gated): Prettier at
printWidth110 is adopted for TypeScript — the one-time repo-wide reformat commit lands after diff review and will be blame-ignored via.git-blame-ignore-revs.cargo fmtis permanently out: measured at 4,770–7,604 structural diff lines regardless of width configuration while only 287 of 18,080 Rust lines exceed 100 columns; clippy-D warningsremains the Rust gate.
Removed
.xlsand.odspassive previews. They rendered through SheetJS only — no editor, no save — which the workspace-not-preview-catalog rule forbids. Open them externally, or convert to.xlsx.- Dead code sweep. Nine unused exports, three unwired scripts, a duplicate slugify (chat renames now share the canonical slug law with chat creation), and two duplicate Rust atomic-write helpers.
Fixed
-
⌥Q / ⌥C no longer surface the main window uninvited. Summoning a floating panel makes macOS fire a spurious Reopen; the suppression was a 700 ms time-box that could lose the race under startup load, opening main alongside the panel (the old “⌥. also opened main” bug, back). The latch is now consumed by the first Reopen and the grace is 2 s — one summon swallows exactly one Reopen, and a genuine Dock click always gets through (unit-tested).
-
Slash and block menus flip upward near the window’s bottom edge instead of being clipped — in the short Quick Note window a bottom-row
/menu was cut off, which read as “slash doesn’t work”. (Quick notes have always had the full editor: slash commands, wikilinks, and embeds included.) -
The quit flush now covers the Quick Note and capture webviews. The handshake only reached the main window, so ⌘Q with the Quick Note focused could drop its last half-second of typing; Rust now waits for every live webview’s ack (still bounded — quit can never hang).
-
Settings → Hotkeys tells the truth when the OS refuses a chord. If a launcher owns a default (⌥Space lovers), the chord now shows unbound instead of claiming a shortcut that silently never fires.
-
Keyboard focus is visible on the capture card and the Quick Note search (accent hairline on focus), and the app-icon call no longer runs three times at boot (once per webview).
-
⌘Q can no longer eat your last keystrokes. The note editor’s debounced save and the settings/viewstate writer are now registered with — and actually awaited by — the quit handshake; previously a quit with the window focused could drop up to 400 ms of typing and in-flight settings writes.
-
A body save can’t resurrect a stale pin. Rust preserves
pinnedfrom disk on every write (likeorigin), closing the read-modify-write race and removing one IPC round-trip per save. -
Atomic writes survive power loss. The shared write helper fsyncs the parent directory after the rename; before, a crash was safe but a power cut could drop the final save.
-
Breve datestamps respect your timezone. Five runtime scripts stamped “today” in UTC, so late-evening briefs, transcripts, and generated files carried tomorrow’s date; all now flow through the timezone-aware helper. The strict typecheck also caught
audio-topic.tscrashing on start (an unimported constant) and an unread-mail scan crash when an IMAP search fails. -
Breve no longer multiplies after Rotli restarts. Its scheduler now has a crash-recoverable singleton lock, exits with its owning app even after an ungraceful parent death, and claims each job across processes before running. Signal/email delivery, provider fallback warnings, creator alerts, and watcher failure notices are concurrency-safe, preventing duplicate briefs and alert floods while preserving retries and durable receipts.
-
Untouched DOCX drafts now disappear when their final tab is closed, note headers and menus expose a direct secure-gated “Chat with this note” flow, the obsolete “File to the Brain” menu is gone, and editor popovers use quiet borders instead of glow shadows.
[0.32.3] - 2026-07-12
Fixed
- DOCX font controls stay readable in dark app environments. The fixed light document toolbar and its portaled font menus now use black labels, visible disabled text, and explicit hover and keyboard-focus states instead of inheriting Univer’s white-on-dark option styling.
[0.32.2] - 2026-07-12
Changed
- DOCX now opens as a predictable Word page. Documents settle before they become interactive, open at the top with one complete page fitted to the pane, use white paper with black Arial defaults, and omit Univer’s margin-corner guides. Table insertion retains the caret while its dialog is open, recovers a dropped editor command into a real OOXML table, and remounts the structural edit so the table appears immediately. Numeric fields remain legible in dark app environments, content changes activate Save, and zooming alone no longer marks a document dirty.
- Sheet embeds now finish loading. The Markdown
sheetfence keeps its Univer host mounted beneath loading and error states, allowing an existing workbook selected from the slash command to initialize and become editable.
[0.32.1] - 2026-07-12
Changed
- Files now stay recoverable inside the memex. Archive and Trash move storage assets beneath the corresponding memex folder while retaining their original storage path for collision-safe restore. These actions never invoke macOS Trash, and stale file tabs/Main/Quick references are removed cleanly.
- DOCX is conventional paper in every environment. The Word editor now uses fixed light chrome and white pages, automatically fits a complete page to the pane without horizontal panning, survives app-theme switches without remount, and hides Univer’s Markdown-like paragraph/block handle. PDF frames likewise request their normal light rendering. Context menus no longer cast a glow.
[0.32.0] - 2026-07-11
Added
- Word tables are editable in Rotli. DOCX tables now travel through the framework-free document model and Univer adapter, and cell edits, formatting, rows, columns, widths, and supported merges round-trip through the OOXML codec. Unrelated package parts and unsupported Word objects remain preserved.
- Legacy documents have a local copy-to-DOCX path.
.doc,.rtf, and.odtfiles can create a new managed DOCX through the macOS system converter without an account, cloud service, or overwrite of the source. Formats without a faithful route are labeled unsupported rather than shown as document previews.
[0.31.0] - 2026-07-11
Changed
- Secure notes now live inside the Brain. New and explicitly migrated secure
notes use the protected
wiki/_secure/lane, preserve their previous physical home for removal of protection, remain gitignored through moves, and are hard- blocked from organizer writes and remote AI reads. “Show in Brain” now targets the requested note directly, and file metadata shows its derived absolute path. - Managed files have an honest lifecycle and editable document boundary. Storage files can move to recoverable Trash from their context menu, open duplicate tabs are closed safely, and DOCX files now open in Rotli’s local document editor. Saves round-trip the Word package through a replaceable codec, preserve unmodeled package parts, keep a one-time backup, and work from both dedicated tabs and Markdown embeds.
- Rotli is explicitly a workspace, not a preview catalog. Images and video are the only preview-only surfaces. Other file formats must provide native editing and saving or an explicit local conversion/import workflow before the product describes them as supported. Document slash commands now list only DOCX-family files that the embedded editor can actually edit.
[0.30.0] - 2026-07-11
Changed
- Secure notes are private by construction. Quick captures and Quick Notes are secure at birth; remote/frontier models can never receive their titles, snippets, or bodies, while loopback-local AI requires an explicit per-note permission. Secure files are also gitignored and have a dedicated destination.
- New item creation is one consistent workflow. New menus offer Markdown, DOCX documents, XLSX sheets, and boards; every entry point uses the same memex routing, refresh, Main-reference, and tab-opening sequence. ⌘T remains Markdown by default and its item type is configurable in General settings.
- The repository now enforces its structural rules. Source modules use camelCase filenames, domain/application boundaries are checked, database dependencies are denied, and slash embeds are kept inside Markdown surfaces.
- Brain retrieval adapts to the selected model. Model Mapping 0 generates a bounded table of contents from context capability and transparent user signals (pins and recency), without a database or duplicate knowledge files.
- Past notes and chats form one master memory. Every persisted chat now
maintains a linked background Markdown summary note, while
search_memoryexpands keywords across organized notes and original chat transcripts beforeread_memorygrounds the answer in the selected source. Remote retrieval skips secret-shaped chats and keeps the provider egress backstop. - Gemini 3.5 Flash can manage the Brain. The organizer can use the existing authenticated, sandboxed Antigravity lane while retaining secure/locked-note egress protection and the provider’s process-wide concurrency gate.
- Rotli Documents now follows an enforced clean-architecture boundary. Framework-free document models and use cases depend on injected storage, encoding, and preview ports; one composition root selects the Tauri, DOCX, and Mammoth adapters. A build check prevents vendor or UI dependencies from leaking back into the domain/application layers.
- Regression coverage now protects product behavior and visual consistency. Every push and pull request runs the frontend, Breve runtime, Rust, architecture, structure, and production-build checks. A fast design lane additionally verifies all six app themes, shared semantic tokens, focus and reduced-motion behavior, theme resolution, Univer mapping, and WCAG contrast for every Breve PDF preset.
[0.29.0] - 2026-07-11
Added
- Breve is a first-class Rotli workspace. The coffee control swaps the sidebar into Briefs, Watchlist, Routines, and Models without disturbing open note panes. The same control becomes the Rotli mark inside Breve and returns to the main workspace; adjacent note controls remain visible but safely disabled until the user switches back.
- A complete Breve product workspace. Briefs is now an operational delivery history instead of a passive landing page, while Watchlist, Routines, Models, and Configure share one restrained desktop form system with readable guidance, clear save state, compact status communication, and responsive layouts.
- Breve PDF appearance is user-controlled. Choose a built-in restrained PDF theme or customize its paper, ink, muted, rule, and accent colors. The same versioned theme contract is used by preview and delivery rendering.
- Documents belong in the note workflow. Rotli can create local DOCX files, securely preview Word-compatible files, and embed documents and sheets inside Markdown notes. Embedded files expand in place without changing the parent tab, can be resized, and offer an explicit open-in-new-tab action.
- Document samples for hands-on validation. A development-only seeder creates representative DOCX and spreadsheet files in the active local corpus without touching production content.
- Copy-only Breve migration. Rotli can import the fixed
~/brevelibrary into the active memex: Markdown briefs and watchlist become reference notes, creators/pages become app-private routine data, and companion artifacts move understorage/breveBriefs. The importer never deletes legacy files or edits launchd and is safe to run again. - Rotli can take complete ownership of Breve. The explicit takeover moves
private configuration, watcher/creator state, Signal sessions and transcripts,
logs, the brief engine, TTS, mail, rendering, and provider fallback into the
active corpus’s managed
.rotli/breveruntime. One restartable Rotli scheduler replaces the seven Breve launchd jobs, follows timezone/travel and live routine edits, prevents overlapping or duplicate delivery, catches up after sleep, and supervises the always-on Signal assistant. Once takeover is verified, Rotli can move~/breveto Trash and discard migration-only backups.
Changed
- Breve now uses the active Rotli memex. Development reads the configured
corpus instead of inventing a separate
tauri-dev-corpus; production data remains write-protected and Breve configuration edits remain temporary in dev. - Model policy is explicit and provider-independent. Breve exposes Claude Sonnet 5 and the authenticated Codex catalog even when a model is hidden from the general chat picker, while intentionally blocked models remain unavailable.
- Breve implementation seams are swappable. Scheduling, document preview, embedded-file controls, PDF theme resolution, and spreadsheet creation are isolated behind small modules instead of accumulating inside surface components.
- The chat model picker reflects real connections. Models are grouped by local Mac, Claude Code, Codex, Antigravity, and the advanced Gemini API lane; only enabled, installed, authenticated providers appear. The popover is now border-only in Charcoal, has no pale glow, removes duplicate Claude models from Antigravity, and supports complete arrow-key navigation.
- Embedded boards resize and expand in place. Drag the bottom grip to make
a
/Boardembed taller or shorter. Its always-visible Expand control now grows the board inside the current note tab, switches to Collapse, and restores the prior dragged height instead of opening another tab.
Fixed
- Doctor alerts are edge-triggered. An unresolved invariant failure is sent
once, suppressed on subsequent 30-minute checks, and reported again only if it
resolves and later returns. A stale
legacy-repo.bundleis relocated from the managed memex to Rotli’s private app-data backups without weakening validation. - Slash commands preserve the current note context. Board, sheet, document, and note-link commands create or select their own files, embed them in the active note, and expand in place; tabs change only when Open in new tab is requested.
- Brain reveal follows the file, not only its shelf. Notes now retain both their shelf projection and physical Brain folder. A filed note whose shelf is still Inbox therefore reports its real area in metadata and Show in Brain expands and scrolls to the exact Brain row.
- Spreadsheets fully occupy Charcoal. Univer’s workbench now fills the file pane to its bottom edge, and live theme changes rebuild its chrome with the current palette so Charcoal stays neutral instead of inheriting warm clay.
- Corpus watcher writes stay quiet. Watch paths are normalized across macOS aliases and metadata-only events are ignored, preventing app-authored writes from returning as false external-change notifications.
[0.28.1] - 2026-07-09
Fixed
- Sheet chrome under charcoal. Univer no longer paints warm cocoa chrome when the app theme is charcoal (or paper/glass) — cool neutrals match the shell. Raw / Save sit next to Open externally in the file header, and the grid host fills the pane edge-to-edge (no side gutters).
- Show in Brain actually reveals. Staged notes open Captures (forced, not toggled) and highlight the card; Main-curated staging notes highlight in Main. Filed notes expand the Brain chain. An open editor also adopts clean disk reloads so an external/agent edit never looks like a second version.
[0.28.0] - 2026-07-09
Added
- Slash: link a note.
/Link note(aliasesnote/wiki/link) opens a searchable picker over the same note universe as ⌘K and inserts a memex-native[[Title]](or[[id]]when titles collide). Wikilinks render as quiet dotted accent links; ⌘-click opens the target note. - Slash: embed a board or sheet.
/Boardand/Sheetinsert a short fence that points at a corpus.excalidraw/.xlsx(pick existing or create new). The note holds the pointer only; a compact live Excalidraw / Univer surface edits the file on disk, and Expand opens the full pane.
Changed
- The new spreadsheet engine IS the editor now. The “New engine · beta”
toggle is gone — editable
.xlsx/.csvfiles open straight into the Univer engine (the full Excel grammar 0.27.0 introduced), and ⌘S saves through the faithful bridge — the file on disk stays the truth. The clay brand theme, the themed ⇄ raw color toggle, and the quit/hide flush all ride the new path, repackaged undersrc/sheets/(codec · engine · session · shell) so a future engine swap is a few-file change. - Editor opens lighter. KaTeX, Mermaid, and JSXGraph load only when a
matching fence first renders; Excalidraw / Univer embed hosts load only when
a
```board/```sheetfence mounts; SheetJS (xlsx) loads only when a read-only sheet or chat attachment needs it. Features unchanged — the default note-editor path no longer pays for those libraries up front.
Fixed
- Clicking an image no longer turns it into text. A click now selects the
image as an object — outlined, Backspace deletes it — instead of dissolving
it into raw markdown; arrow keys into the line remain the way to edit the
source by hand. - Moving an image shows where it’s going — and comes with you. Dragging an image lifts a small ghost of it that rides the pointer (the original dims in place — the same grammar as dragging tabs and board cards), and draws a live drop-indicator line at the exact landing spot (upper half of a line = before it, lower half = after; the blank space below the note = the end), the note auto-scrolls near the edges, and Escape cancels the drag. Two silent bugs died with it: a downward drag used to land one image-line above the drop point, and a mid-drag redraw could scatter the image to the wrong place entirely. Drops also snap out of tables and code fences instead of splitting them.
- Resizing a bulleted image no longer eats the bullet. The resize grip
used to rewrite the whole line and wipe the
-prefix.
[0.27.0] - 2026-07-09
Added
- A new spreadsheet engine, in beta. Editable
.xlsxfiles grew a “New engine · beta” toggle: the full Excel grammar — row/column header selection, ⇧-click ranges, a formula bar with live-calculating formulas, fill handle, copy/paste, undo/redo, resize, merge, freeze — powered by Univer’s free Apache-2.0 engine. The file on disk stays the truth (rotli keeps its own codec); edits in the beta don’t save yet — the faithful save bridge is built and round-trip-tested, and flips on after the soak.
Fixed
- The formula trap. Typing
=SUM(…)into the current editor used to be silently saved as literal text; it now refuses loudly and saves nothing. - The context menu tells the truth now. Show in Finder actually reveals the note (its Rust command never learned that notes travel as ids, not paths — it failed silently for months); Pin to top actually pins — pinned notes float above your hand-arranged Main order and the Captures order (the arrangement itself is never touched) with a quiet pin marker; Open in Brain became Show in Brain and handles staged notes (a capture’s brain home is the Captures board, so that’s what opens — the old reveal visibly did nothing). And when any of these fails, the sidebar says so instead of swallowing it.
- Images work inside bullets. An image on a list line (
- ) renders inline after the bullet/number/checkbox instead of staying raw markdown forever. - The phantom gap next to the star is gone. Main rows reserved an invisible hover-× slot that read as a broken hole; removing from Main lives in the right-click menu.
[0.26.1] - 2026-07-08
Added
- Back / Forward. The titlebar grew ‹ › buttons beside search — walk your trail of opened notes like a browser (⌘[ and ⌘] too). The history was being recorded all along; now there’s a way to travel it.
- The ⌘K palette finds more. Files by name (that PDF in Storage is one keystroke away) and chats by title now show up alongside notes and actions. Result rows got richer, too: a title match highlights the matched letters, and a body match shows the note’s home and the snippet instead of one or the other.
Fixed
- Other themes no longer creep in. Three real leaks, all sealed: native
dropdown menus and scrollbars now follow rotli’s theme instead of the OS
appearance (
color-schemeper theme); the ⌘-hold shortcut overlay’s blur was hardcoded warm-cocoa and painted the warm theme over Paper/Charcoal/ Glass — it now uses the theme’s own scrim (glass got a proper one); and a latent CSS block that quietly re-applied warm-dark colors on dark-OS Macs was removed.
[0.26.0] - 2026-07-08
Added
- A real spreadsheet editor. The sheet surface grew from cell edits into a Sheets-style suite: a formatting bar (font family + size · bold / italic / underline · text + fill color · borders · wrap · alignment), range multi-select (drag a rectangle, ⇧ extends, ⌘ toggles single cells in or out, arrows walk and ⇧+arrows extend), insert / delete rows and columns (right-click a row number or column header), and a Live ⇄ Theme color toggle — Live shows the sheet’s true colors on a paper canvas exactly as Excel would, Theme lets it blend into rotli. Display only; the file always keeps its real colors, and ⌘S remains the only write.
- Chats are first-class in the sidebar. Right-click a chat for Pin to
top (rides the chat’s own frontmatter), Rename… (inline), Archive,
and Delete — archive/delete move the file into hidden
chats/archive//chats/trash/, so nothing is ever hard-deleted.
Fixed
- Deleting a storage file from Main no longer errors. A binary in the memex
storage/is an asset, not a note — removing it from Main just unpins it (the old path tried to trash a “note” that didn’t exist and failed). - Main only shows what really lives in your memex. A note moved to Archive/Trash (or living in an external vault) no longer lingers as a phantom Main row; trashing or archiving a pinned note also unpins it.
- Open in Brain actually opens the Brain. It now reveals the note’s real
wiki/home even when the note is also pinned in Main (Main used to win). - The destination highlight tells the truth. Brain/Storage/Archive/Trash rows only read as selected while the content you’re focused on actually lives there — a stale ⌘N target no longer glows while you work elsewhere.
[0.25.0] - 2026-07-08
Fixed
- Excalidraw boards save in a memex again. A board like
call-w_Jorgeliving in the memex’sstorage/excalidraw/was refused every save (“this board isn’t saving — read-only here”), becausestorage/is read-only to rotli. Boards now have their own writable lane:storage/excalidraw/is a rotli-owned surface, so boards edit and save while the rest ofstorage/stays read-only. New boards in a memex land there too. - Spreadsheets in your memex are editable now. An
.xlsx/.csvliving in the memexstorage/(likecompany-overview.xlsx) opened read-only, becausestorage/is read-only to rotli. Existing sheets there now edit in place — double-click a cell, ⌘S saves, and a one-time.bakkeeps the original — the same writable-lane idea as boards. Creating brand-new files instorage/stays refused.
Changed
- rotli’s docs now live in the memex, not this repo. The living docs (model,
design-system, philosophy, vision, the Main/Brain daemon spec, design notes,
audit logs) moved into
memex-vault/wiki/projects/rotli/, surfaced under a Rotli folder in Main — so project planning + docs are organized in rotli itself. The repo keeps only the README (+docs/mediaassets anddocs/archivehistory). CARL + code references now point at the memex. - The in-chat model picker is a real picker. The composer’s plain dropdown
became a quiet grouped popover — On this Mac · Connected · Presets — with a
local-vs-“this chat leaves your Mac” cue, a 👁 badge for vision models, a
defaulttag, and the current pick checked. Same low-pulse grammar as the width menu. - AI Models settings read at a glance. Constructive actions (Install / Add / Save / New) now take a restrained accent while destructive ones (Uninstall / Delete / Remove) step back to muted — hierarchy without any loud fills.
- Sidebar create icons are centered. New note · New folder · New board · Collapse all now sit as a centered cluster.
Added
- More ways into Main. Right-click a tab → Add to Main (note and board tabs). And you can now drag into Main from two more places: an editor tab and a row in the All notes list — the hovered Main row highlights and the note lands where you drop it (a plain click still just opens it).
- Settings → Plugins: “Use rotli for your docs.” A copy-paste command for Claude Code that routes a project’s planning + docs into rotli instead of the repo (README excepted).
- Rename a chat — right-click (or double-click) a chat tab → Rename…
renames
chats/<slug>.mdon disk and re-points the open tab. - Find any note. Right-click → Show in Finder (reveals the file) and Open in Brain (opens it and reveals where it lives in the sidebar — Main is just a view). The editor’s location chip now shows the note’s Brain folder + its absolute on-disk path in its tooltip.
- First-run model setup. Onboarding now has an Its mind step: grab a small on-device model in one click (the download keeps going if you continue), or skip and connect a subscription later in Settings — so a fresh install lands with a working chat. Optional; it never blocks setup.
Onboarding + demo-mode polish.
Fixed
- Demo mode no longer forces you through onboarding. It swaps only the notes memex now — your per-machine settings (look, shortcuts, and the onboarded flag) keep reading your real corpus, so turning demo on just changes what notes you’re looking at, temporarily.
Changed
- Onboarding no longer offers Liquid Glass. “Pick a look” is four solid base themes; Liquid Glass stays an advanced mode you discover in Settings.
- Onboarding’s Continue button is locked in place. Skip moved next to the progress dots, Back holds its slot on the welcome step, and the primary button has a fixed width — so Continue never shifts between steps.
- The seeded demo library is public and about rotli itself. Replaced the personal/work sample notes with a general getting-started set (Welcome, Main & the Brain, note-taking, local-first) and seeded a hand-arranged Main so the demo shows the same note reachable two ways — in Main and in the Brain.
[0.24.7] — 2026-07-07
Archive/Trash/boards work in a memex now, plus a seeded demo library.
Fixed
- Archive, Trash, and new boards work when your notes folder is a memex. They were silently refused by the memex write-gate (Archive/Trash/new-board targets weren’t writable), so they appeared to do nothing. Archive/Trash are now a sanctioned rotli lifecycle lane, and ⌘⇧N (new Excalidraw board) stages into the memex. Any refused lifecycle move now shows an inline error instead of silently failing.
Changed
- Dismissing a note from Main deletes it when it’s empty (no title + no body); a note with content just unlinks from Main.
Added
- Demo mode (Settings → General): switch to a seeded demo library
(
memex-demo, next to your real memex) with sample notes, boards, and a chat — for clean screenshots or trying things out. It’s marked demo-only in its own config, so onboarding never sees it, and your real notes are never touched. Toggling relaunches.
[0.24.6] — 2026-07-07
Titlebar search, a calmer charcoal, and an app-icon picker.
Added
- App-icon picker (Settings → Appearance): choose the Dock icon — Default · Paper · Charcoal · Clay (the quokka re-tiled in each palette). Persisted and applied on launch; shows when Show in the Dock is on.
Changed
- Titlebar search reworked. The field is wider, the rotli mark moved off the
far left and into the field as a circular badge (in place of the search
glyph), and the ⌘K hint is quieter (no card). The sidebar’s “Filter
notes…” field is gone — the global search covers it (and
/opens it). - Liquid Glass is “Coming soon” — the section still previews, but the toggle is disabled for now.
Fixed
- The ⌘K palette no longer reads warm-brown in Charcoal. Its dim is a theme token now — warm in the warm themes, neutral in the mono ones.
[0.24.5] — 2026-07-06
Pin + a global titlebar search, a repo-wide cleanup (brand & docs now live in-repo, aligned to the current three-fronts model), and a new minimal marketing site.
Added
- Pin a note to the top. Every note now has a real Pin — the row’s
right-click menu gains Pin to top / Unpin from top, and ⌘⇧P pins (or
unpins) whatever note you’re on. Pinned notes float above everything in All
notes (and sort first in their sidebar folder), marked with a small pin.
Pinning writes the note’s
pinnedfrontmatter fact and never bumpsupdated, so it doesn’t reorder the note by recency. Locked/secure/Main rules are unaffected. (Newcorpus_set_pinnedcommand.) - Global search in the titlebar. The rotli mark moved to the top-left beside the sidebar toggle, and a Search… field now sits at the top center — click it (or ⌘K) to search every note and action.
Changed
- Settings toggles lost the hard outline. The on/off cards are now soft filled panels instead of bordered boxes — the bright accent outline the “on” state drew (near-white in the dark themes) is gone; the switch alone shows state.
- All notes = every note except Archive and Trash, newest first (pinned above that) — and a staged Capture shown there now gets the full right-click menu instead of a dead Restore that did nothing. Restore is reserved for genuinely archived/trashed notes again.
Fixed
- Folder-row hover icons no longer drift apart. The New note / New folder pair on a folder’s hover now rides the right edge together instead of splitting the free space between them.
Website
- New marketing site (
site/, Astro) — a minimal, Ollama-style landing page built around the quokka mark as the logo, in the Paper (light) / Charcoal (dark) black-&-white theme pair. Self-contained; its own deps, doesn’t touch the app’s lockfile.
Docs, brand & repo
- Brand + docs now live in the repo. rotli’s brand kit is the app-embedded,
hex-enforced
src/brand/(single source of truth); provenance/history is underbrand/engine-history/; docs are indocs/. (Migrated out of smLab.) - Everything aligned to the current model. README, the brand copy
(
brand.json/kit.json), and the promoted docs (docs/vision.md,docs/philosophy.md,docs/design-system.md) were rewritten from the old “six fronts / Voice / Memory / bundled LLM” framing to the three-fronts memex model; stale/duplicate rough-drafts were removed. - CARL refreshed — the project rules now describe the in-repo brand/docs and the correct contract band [3.4, 3.7].
[0.24.4] — 2026-07-03
The tab model, the note-location finder, and the Batch 2 sidebar pass — plus the first foundations of the Breve→rotli merge.
Added
- Every note now shows where it lives. The editor header has a clickable
location — e.g.
Projects,Storage › Images,Captures, and ★ Main when the note is in Main (Main membership stays out of the frontmatter by design, so this is the signal). Clicking it reveals + scrolls to the note in the sidebar (expands its Main-folder chain, else its Brain area). Notes not in Main can be added from All Notes via the row’s right-click menu.
Changed
- Clicking a file follows the standard editor model now. A plain click in the sidebar activates that file’s tab if it’s already open, otherwise opens it in a new tab — it never replaces the file you’re working in. ⌘-click / ⌘T still force a fresh tab. (Previously a plain click replaced the active tab, so opening a second file lost your place.) Applies to notes, boards, files, and saved chats; “New chat” always opens fresh.
Sidebar structure & navigation (Batch 2)
- Chat list shows 5 by default (feedback #17), with a 5 / 10 / 15 picker in Settings → AI Models (“Chats in the sidebar”). The old flat cap of 12 is gone.
- The current file is highlighted in the sidebar and its folder auto-expands (feedback #25) — the Main copy wins the highlight; a note not in Main is revealed in the Brain. Only reveals on navigation, never fighting a manual collapse.
- IDE-style create icons (feedback #7 / #13): the old “+” dropdown became explicit VS Code-style New note · New folder · New board · Collapse all icons in the sidebar toolbar, plus a new-note + new-folder pair on each folder’s hover (content lands in that exact folder). The toolbar wraps on a narrow rail.
- Stars-column whitespace fixed on Main rows (feedback #9): the star and × now ride flush to the trailing edge instead of leaving an awkward gap on short titles.
- Back/Forward navigation history substrate (feedback #14): a new
src/state/navHistory.tstrail records every opened note (replayable, capped). The ‹ › buttons + the filter’s move up by the wordmark, and the IDE-style search dropdown (feedback #26), are deferred to a dedicated follow-up.
Fixed
- No more ghost tab on launch. With the new tab model, the app’s pristine startup tab is now filled with your freshest note instead of leaving an empty tab beside it (caught by the pre-release review).
Internal
- Breve→rotli merge, P0 foundations: a pure
src/routines/layer (types, a tz-awarenextRunscheduler, a watchlist parser) and an additive Rustprovider_chainfallback helper — groundwork for scheduled briefs, not yet wired to anything. Design indocs/design/breve-merge.md.
[0.24.3] — 2026-07-03
Feedback sweep, day 2: organizer controls (pick the model + idle delay), the Breve check-up fix, and the metadata/onboarding polish from the maintainer’s live pass.
Added
- Pick the organizer’s model (Settings → Brain). Choose On this Mac (the
local MLX model — default, nothing leaves the machine) or Claude Sonnet 5
(via
claude -p). With the Claude lane, non-secure notes are sent to Anthropic to file; secure and locked notes are never sent anywhere (a hard guarantee in the daemon). The Rust daemon re-reads the choice each cycle. - Set the organizer’s idle delay (Settings → Brain): 1 / 2 / 5 / 10 / 15 min. A note is only scanned after it’s sat untouched that long — the default is now 5 minutes (was 45s), so the organizer waits until you’ve moved on.
Changed
- The metadata (≡) icon is now an instant toggle (feedback #23). Clicking it
shows/hides the note’s frontmatter immediately — no more popover. The controls
that lived in that popover — Lock from the AI, Mark secure, and File
to the Brain — moved into the note’s right-click menu (alongside the
existing Add-to-Main / Star / Rename), reachable by right-clicking a note in the
sidebar or the editor’s header chrome. The old
MetaPanelpopover is retired. - An open note now shows “★ In Main” in its header status line when it’s in
Main (feedback #1). Main membership is deliberately not in the note’s
frontmatter — it lives in
.rotli/main.jsonso the AI reorganizing the Brain never disturbs your arrangement — so this is the glanceable indicator that was missing, plus Add/Remove-from-Main in the right-click menu.
Fixed
- Dropped images no longer create “broken asset” refs.
import_filecopied a dropped file intostorage/with its original name, so a macOS screenshot (“Screenshot 2026-… AM.png”) produced a spacedstorage:link that breaks markdown and the memex validator’s[A-Za-z0-9._/-]regex — the recurring Breve check-up failures. Names are now slugified on import (screenshot-2026-…-am.png); the existing rotli-feedback note’s 16 refs + files were de-spaced sovalidate.tspasses. - Onboarding no longer shows your one brain twice (feedback #6). When the memex rotli auto-detects on the Mac IS your current notes location, the “Use …” card was the same folder as “Keep my current location” — two cards, one folder, where picking “Use” just relocated you to where you already were. The detected list now drops any memex whose path equals the current location, so you’re never offered the same folder twice. (Pulled forward from Batch 7.)
[0.24.2] — 2026-07-03
The 2026-07-03 feedback sweep begins (26 items, shipped in subsystem batches —
tracker in docs/design/feedback-2026-07-03.md). This release is Batch 1 of 7 ·
Tabs & Main core.
Changed
- ⌘T opens a new blank note, not a duplicate (#8). The tab-strip “+” and ⌘T
both created another tab of the same note; now they open a fresh note in a new
tab — the IDE “new tab” gesture. The old duplicate-the-active-tab
newTab()store method is retired (splits still duplicate, unchanged). - Every new note auto-files into Main (#15). ⌘N, the “+” menu, and ⌘T now drop the new note into Main the moment it’s created — Main is your main work area, so a new note shows up there immediately instead of only in Captures/Brain.
- A new note inherits the Main folder you’re working in (#16). Create a note
while an in-a-Main-folder note is active (or with a Main folder selected) and it
lands in that same folder; otherwise it lands at the Main root. A
main:<path>selection is treated as a view, never a disk path, so physical creation still routes normally (memex staging / local Inbox) — only the Main slot follows.
[0.24.1] — 2026-07-02
The first-contact fixes from the maintainer’s live pass over 0.24.0.
Fixed
- The lane toggle now actually flips. The bare switch in a lane card was missing its ON-state styling (the knob styles only existed under the old full-row toggle), so an enabled lane looked OFF — the “enabled UI is confusing” report. Enabled lanes now show a filled accent switch.
- Preset cards are readable. The one-line summary that ellipsized into raw model ids (“gemma-3-12b-it-qat-4bit · MLX → ge…”) is now a stacked flow: who organizes, each route’s “when → model” on its own line, and the fallback — with human model names.
- Model pills read at a glance: allowed = filled with a ✓, hidden = dashed + struck-through, and the label says what clicking does. Version chips are clean (“ready · v2.1.199”).
Changed
- The Brain organizes by default. The trust ladder’s default rung is now Organize (was Suggest) — across the UI default, the settings parse, and the Rust daemon — because the daemon only ever changes a note’s location + metadata (journaled, undoable); the words inside notes are never touched. An explicit settings choice always wins; the design doc carries a dated amendment.
- Brain pane copy rewritten around that promise: what it touches (location + metadata, never your words), what locked means (lock a note in its metadata panel → the organizer skips it entirely), and when it runs.
The AI Models pane grows up: verification, per-model control, starter presets, and “Scan my Mac”.
Added
- Connected lanes are now cards that prove themselves. Toggling a lane on runs one tiny REAL reply in the background on the lane’s cheapest model (detection only proves a binary + a credential; a ping proves the path) — the card shows “working ✓ · haiku · 2.1s” or the actual error, and a Test connection button re-checks any time. Saving a Gemini key verifies immediately.
- Setup instructions where they’re needed: a lane that isn’t installed or signed in grows a “How to set this up” disclosure with the exact install + login steps.
- Per-model control inside a lane: click a model pill to block or allow it in the picker (e.g. keep Sonnet, block Opus). Blocked models also leave the preset editor. Persisted.
- Starter presets — three ready-made hybrids (Everyday · Private by default · Frontier delegate) with stable ids; add one and tweak it like any preset.
- Scan my Mac: reads the chip, unified memory, and free disk (reference machine: 64 GB), says what weight class the machine comfortably runs, and badges every catalog pick (great fit / workable / too big). The catalog also gained Qwen2.5 14B and 32B for the Macs that can carry them.
Changed
- The whole AI Models pane breathes: sectioned groups with real spacing, roomier rows, cards instead of packed toggles.
- The shared registry’s
updatedfield is now stamped on every install/uninstall.
The pre-test verification sweep: every connected lane’s exact invocation was executed live against the installed CLIs before handing the build over for testing.
Fixed
- The Codex lane was broken on arrival —
codex exec(0.137.0) has no--ask-for-approvalflag (exec mode never prompts; that flag belongs to interactive mode), so every codex chat turn and codex image job would have died on argv parsing. Both recipes drop the flag and gain--ephemeral(no session litter — the codex twin of claude’s--no-session-persistence). A regression test now pins the flag OUT.
Verified (no changes needed)
- The exact claude argv end-to-end (haiku ping →
result/is_errorenvelope parses), the corrected codex argv end-to-end (item.completed→agent_message), the agy argv end-to-end (“OK” on stdout), the claude Keychain detect probe, and all five curated catalog repo ids (HTTP 200 on Hugging Face).
[0.23.0] — 2026-07-02
Install on-device models straight from Settings — and pick any of them per chat.
Added
- Local model installer (Settings → AI Models → On this Mac): browse a curated set of
MLX chat models or paste any Hugging Face repo id, and rotli downloads the weights (via
the memex-ai venv’s
hfCLI) into the shared store with a live progress bar + Cancel, then registers them. Installed models can be uninstalled (registry entry dropped, dir trashed — never a hardrm). - Every installed model is pickable per chat. The shared MLX server (bumped to 0.3,
live-verified) now honors the request’s
model: a known id (registry id or models/ dir name, resolution locked inside the shared store) swaps the single loaded slot on demand. Models load lazily and idle-unload after ~10 minutes — nothing runs 24/7. A request without a model (Breve, voz, warmup) gets the pinned default, byte-for-byte unchanged. - Default model control: one local model is the default — what no-model callers
get. “Make default” repoints the server’s launchd env (PlistBuddy
Set+ a reload); the default model refuses uninstall so other memex apps never lose their model.
Changed
- rotli now writes two shared memex-ai artifacts (it only read them before): spliced
registry.jsonmodel entries and the MLX server’sMEMEX_MLX_MODELlaunchd env. Both are surgical and reversible — the registry rewrite preserves every other key (atomic tmp+rename), and the plist edit is a single valueSet.
Notes
- Connected models (Claude/Codex/Antigravity CLIs, Gemini API) are entirely separate lanes and unaffected by local model choices.
- Downloads shell the venv’s
hfbinary (~/.memex/ai/mlx-venv/bin/hf); a repo id is validatedowner/nameand the install dir name is a safe slug, so a download can’t escape~/.memex/ai/models/. Success is verified by config + weight files on disk, never by the CLI’s stderr. - The shared
~/.memex/ai/mlx-server.pywas updated in place (0.2 → 0.3, backup kept atmlx-server.py.bak-0.2); its registrylifecyclenote documents the new behavior.
[0.22.0] — 2026-07-02
The AI Chat flow, rethought: connected subscription models, hybrid routing, and the chat that organizes itself.
Added
- Connected models (Settings → AI Models): chat can now run on the subscriptions
already signed in on this Mac — Claude Code (Claude Pro/Max), Codex (ChatGPT),
Antigravity (Google AI Pro/Ultra; bundles Gemini 3.x + Claude 4.6 models) — plus a
bring-your-own-key Gemini API lane. Each lane shows a live status chip (installed /
signed in / ready) and an enable toggle; the Gemini key lives in the macOS Keychain
(native Keychain Services — never argv, never a config file, never IPC’d back out).
Rust drives each CLI as a tool-less, sandboxed completion backend under the existing
agent loop (hardcoded binary + model allowlist, kill-on-cancel, per-step deadline;
agy runs single-flight). The picker groups On this Mac · Connected · Presets and is
honest about locality; secure notes stay refused to every connected lane (the
endpoint: ""locality check fails closed + a secret-shaped-transcript egress backstop in the CLI bridge itself). - Hybrid presets: settings-defined routing — an organizer model reads each message and picks a route (“when …” → model); the routed model runs the normal agent loop; an optional fallback retries a failed executor once. Presets ride the model picker as pseudo-models, statuses narrate the hops (“routing via gemma… → Gemini 3 Pro”), and routing never fails a turn (garbage/organizer-down → first route). Generate templates drafts three presets from “what do you mostly use chat for?”.
- Every chat carries a note: the chat header’s note button opens the chat’s attached
note — materialized lazily into
wiki/_inbox/staging on first open (attachedTo:frontmatter + the note’s## Chatbacklink) — as a new tab or a right split (Settings → AI Models → Chat & its note). - Chat width: Narrow / Comfort / Wide from the chat header — the notes Aa measure vocabulary, per-chat, persisted, carried from an unsaved chat to its slug on first send.
generate_imagechat tool + assets drawer: chats on a connected engine (Codex gpt-image / Antigravity Nano Banana — a Settings radio) can generate images; PNGs land instorage/chats/<slug>/(path pinned by Rust from a registered root + safe slug — the model never shapes it; postcondition: the file exists non-empty). The header’s assets button opens a thumbnail drawer; a click opens the file in a tab. Image prompts ride the same secret-egress guard as the web tools.
Changed
- The send button is a button now — a filled circular ↑ (ChatGPT/Claude style); spinner while a local model thinks, a real stop square for connected models (Rust kills the subprocess mid-step).
- The agent loop grew a frontier adapter + 200k budget tier for connected models (terser system-style scaffold, same one-JSON tool protocol, deeper read/history/step caps) — local models keep the tuned Gemma scaffold and their exact tiers.
Notes
- Personal-use lane: rotli drives the user’s own installed, signed-in CLIs on their own machine. Distributing this to other users would need each vendor’s blessing (Anthropic requires approval for third-party subscription auth) — fine for 0.x.
- Gemini CLI’s OAuth/subscription lane died 2026-06-18 (Google’s transition to
Antigravity); that’s why the Google-subscription path is
agyand Gemini is API-key-only.
[0.21.1] — 2026-07-02
Added
- Three new quokka poses —
waving,searching, andcelebrating— generated against the base character as a style reference (gpt-image-2), binarized, and vector-traced back into the set’s single-pathcurrentColorformat. Same character, same line weight, big catchlight eyes. - Onboarding got its moments: the welcome step now greets you with the waving quokka, and
the final “You’re set” step celebrates (confetti).
searchingis vendored and registered, reserved for a future search surface.
[0.21.0] — 2026-07-02
The quokkas, properly.
Fixed
- The eyes read as eyes now. Every character’s eye-highlight hole doubled (17→34 viewBox units) — at empty-state sizes the eyes now carry a visible catchlight instead of collapsing into blobs. (The set is single-path evenodd line art; the holes were simply too small to survive rasterization below ~120px.)
- Every character file was mislabeled. The original export’s filenames were rotated one pose off — “base” was the shield, “stays_local” the easel, “knowledge_system” the laptop, and so on around the whole set. Re-vendored with each file carrying the pose its name claims, so every placement finally shows the RIGHT quokka: onboarding’s “stays local” step gets the shield+padlock, the chat empty state gets the laptop+speech bubble, Settings pane accents all match their panes.
Added
- A new
restcharacter — closed eyes, same hand-drawn line grammar (derived from the base pose) — for quiet empty states. - Quokkas in more empty states: All notes (“No notes yet” → the notepad quokka), All chats (the laptop quokka), Captures (“Nothing captured yet” → the resting quokka), and Brain → Activity (“Nothing yet” → the knowledge quokka). Search “no matches” states stay art-free — they’re transient, not empty worlds.
[0.20.0] — 2026-07-02
The audit release. A deep adversarial review of v0.19.0 —
docs/audit-2026-07-forge.md, 97 verified findings
across structure · UX · AI, from one critical to small polish — followed by a fix train
that landed 54 of them in four batches: the security batch first (several findings
were armed against a vault that really holds SSNs and card numbers), then data-safety +
daemon correctness, then the bug-class UX fixes and cheap enhancements, and finally this
honesty pass over the docs. The rest of the findings stay tracked in the report (the
performance batch and the mega-refactors are sequenced there, not forgotten).
Fixed — security & secrets (the batch that shipped first)
- A secure note’s
.gitignoreline now follows the file (the audit’s one critical, #1) — flagging a notesecure:gitignores it, but renaming it, filing it to the Brain, moving or undoing it used to leave the OLD path in.gitignore, silently making the secret committable. Every relocate/rename now re-syncs the gitignore entry (remove old, add new), test-pinned through the flag→file→assert loop. - “Local model” is verified, not assumed (#2) — secure notes were gated by a
hardcoded
true; locality is now derived from the picked model’s actual endpoint (loopback check, TS + Rust in lockstep), so a registry entry can’t masquerade as local and walk off with a secure note. - Secret detection runs at the AI boundary too (#21, #23) — a note that looks
secret (even if its metadata panel was never opened) is refused to remote models,
and the detectors on both sides now catch separator-less card numbers
(Luhn-checked 15–16 digit runs) — the exact shape in the migrated notes. Dash-less
SSNs carry no checksum, so a bare 9-digit run still isn’t flagged (too many false
positives) — dashed SSNs are caught, and the
secure:flag covers the rest. The transport itself now re-checks too:chat_messagesrefuses a secret-shaped transcript to any non-local endpoint, the same backstop web search/fetch already had. - The write gates got their missing teeth (#3, #22, #20, #44) — a brain’s
“read-only” perms + contract band are now enforced in Rust, not just TS;
corpus_set_fieldrefuses AI-owned keys and honorswritable(); thememex_*commands only accept registered roots (a webview can no longer point them at an arbitrary path); and the daemon-ownedorganizer.jsoncan’t be wiped from the webview settings lane. - Contract honesty — the TS/Rust contract band re-locked at [3.4, 3.7] with a
lockstep test (#24); the file-lock now fails closed instead of proceeding
unserialized after 10s (#42); five registered-but-unwired commands — including
corpus_purge, the only hard-delete lane — are unregistered until something real calls them (#68); an inverted secure-policy comment that a future re-sync would have propagated is corrected (#31); and the contract surface is narrowed to what actually runs: the TS “Filer tier” is documented as the Rust lane’s mirror, not a live TS path (#95), andinbox.md— a declared write surface no code ever wrote — is out of both write gates (#96; captures stage inwiki/_inbox/, Breve owns its own inbox appends).
Fixed — data safety & correctness
- Dirty spreadsheets survive quit (#4) — unsaved sheet edits used to die silently with ⌘Q; every parked dirty session now flushes through the real save path the moment the window hides (the same seam settings flush on) — and quit itself is intercepted: ⌘Q and tray-Quit ask the webview to flush first and hold the exit (bounded at 2s, quit can never hang) until it acks, so edits survive even when no hide ever fired (“Stay open” mode, quitting from the focused window). Explicit Save stays the law while you work.
- ⌘N can’t create a note in Archive/Trash (#5), the ⌥Q quick-note target can no longer be pointed at a folder the gate refuses (and a refused capture says so instead of breaking the hotkey forever, #6), and a fresh chat no longer inherits web-ON from a stale unsaved-chat toggle (#7 — the silent-egress default stays off).
- Vision actually sees (#8) — the MLX generate path never forwarded the attached image; the composer’s only vision model was confidently answering about pictures it never received. The image bytes now ride the request.
- The chat agent searches full text (#9) —
search_notesnow rides the realcorpus_search(title + body, ranked, snippets) instead of keyword-ranking 140-char snippets; long conversations are budget-trimmed instead of overflowing small-model context (#65); futile tool calls count toward the loop’s two-strike exit (#93). - Daemon correctness — a failed mid-apply write can no longer strand a capture as
“already classified” (state mutates only after the writes succeed, #25); index
proposals get the same supersede + approve-time freshness grammar file/field rows
always had (no more zombie rows or stale-approve overwrites, #26); a frontmatter
edit made during a model call is no longer clobbered by the apply window (#27);
approving a proposal now teaches the daemon the approved value is daemon-owned
(it used to freeze the field forever — cooperation reduced maintenance, #28); an
explicit Run now on battery is queued instead of silently swallowed by the power
gate (#29); and approved filings carry the same
filed_by/filed_ataudit trail as auto-applied ones (#90). - State that survives a relaunch — open spreadsheet/Activity tabs no longer vanish
at startup (the viewstate validator knows all five tab kinds now, #34); a hand-set
unknown key in
settings.json(like the daemon’s documented threshold knob) is round-tripped instead of destroyed by the next theme toggle (#35); renaming a board keeps its committed Main slot instead of letting the manifest GC eat it (#33); and the two long-lived persisted maps that never forgot a chat/folder are GC’d (#78). - Small but real — ⌘K opens boards as boards, not dead note panes (#55); j/k no
longer wedges on phantom rows in a linked library’s
_-folders (#45); the sidebar and All-notes counts agree (one universe, and Recent dropped its meaningless total, #60); collapse-all collapses Main too (#83); a real folder named “all” no longer collides with the All-notes query key (#77); Settings hotkey copy shows your actual chords after a rebind (#86); a chat pane header shows the stored title, not the de-dashed slug (#87).
Changed / Added — the UX batch
- Failures surface where you work (#11) — a failed board write shows a data-loss strip over the canvas; a failed chat save renders an inline “won’t survive a reload” note; a failed file-to-Brain or board rename lands as a dismissible sidebar note. Nothing important dies in the console anymore.
- Re-onboarding keeps your notes where they are (#12) — a 0.x update’s onboarding now pre-seeds a selected “Keep my current location” card; clicking through can never relocate the corpus. (A true first run still requires the explicit choice — the v0.8.7 no-silent-default rule stands.)
- Generic code fences render as code (#13) — a
js block (or a bare) keeps a mono voice; its contents are never markdown-styled, and a pipe-table example inside any fence is never turned into a live table widget (the slash menu shipped the repro). - Links open (#14) — ⌘-click a markdown link (raw or beautified) to open it, with a tooltip that says so; plain click stays the edit path. Rendered links (chat bubbles, previews) open on plain click. Everything routes through one scheme-allowlisted Rust opener — http/https/mailto only, so a link can never launch a file path, app scheme, or flag.
- Main folders are renameable (#16) — inline rename (context menu or the row), and the ⊕ is now name-first: it opens an input instead of minting a permanent “New folder 2”.
- Honest labels — the Aa panel’s global rows say “· all notes” instead of hiding behind the per-note footnote (#52); a read-only sheet says why (“view only · .ods” / “· too large”, #53); the PDF pane takes keyboard focus so space/arrows page immediately (#54); the Captures board quietly explains that a curated card graduates — it leaves the board and lives with your notes — and the cards carry the app’s right-click menu (star · Add to Main · File to the Brain · archive), so graduating happens where the captures live (#56).
- Small pleasures (#80–#85) — a theme-aware checkerboard behind transparent images; middle-click closes a tab; Main’s empty state only mentions the Brain when a Brain exists; Approve gets a quiet accent (no longer Dismiss’s twin) and “· 78%” became “· 78% sure”; Run now stops claiming “Running…” forever and its errors render styled.
Docs
- The design doc tells the shipped truth (#30) —
docs/design/main-brain-daemon.mdnow marksreach:scoping (§4.2.6), the configurable battery budget (§6.3), and the Settings → Brain capability checkboxes (§4.8) as Phase-5 deferrals instead of implying they shipped with the daemon.docs/model.mdrefreshed for everything user-visible above.
[0.19.0] — 2026-07-01
One release, three batches. Phase 4 of the Main/Brain plan
(docs/design/main-brain-daemon.md): the organizer daemon — your notes get organized
while you’re not looking, on-device, logged, reversible, and easy on the battery.
Plus the files/metadata batch and an editor · search · viewer batch.
Added — the organizer daemon (Phase 4)
- The Suggest daemon (
organizer.rs) — an event-driven Rust background worker that runs three narrow jobs against the local model: Classify (stagedwiki/_inboxcaptures → an area, or asuggested_areahint below the confidence threshold), Enrich (fill emptysummary/tags/links— a field you edited is never clobbered; link candidates come from keyword ranking, the model only confirms), and Refresh index (deterministicwiki/<area>/_index.mdoverviews — same members, same bytes, no thrash). Gated to run politely: per-note quiet period, user idle or app backgrounded, on AC, thermals OK, and it always yields to an interactive chat. - It preserves your computer — the daemon never polls and is never “running 24/7.”
Work is scheduled only by the file watcher (a quiet-window debounce folds a typing
burst into one run after the last save settles), by an Approve/Dismiss/Undo you
make (which owes it one reconciliation sweep — the old 15-minute polling sweep is
gone), or by Run now. With nothing staged it parks outright: zero wakeups, no
tick, no timers, no settings reads, no
pmsetshell-outs (locked by a scheduler test — an idle corpus plans exactlyPark). Off on battery by default (the design doc’s §6.3 call); a hot machine backs it off; and it never keeps the model warm — no keep-alive/warm-up calls exist, so the model server’s own idle-unload governs. - “Run now” — Settings → Brain and the Brain Activity header both carry the explicit nudge: one pass immediately (even on battery — it’s your deliberate call), then back to sleep. It still never interrupts an in-flight chat.
- Approve/Dismiss review lane — proposals land in Brain → Activity (“🧠 Proposes: File ‘Foo’ → Projects · 91%”) with one-click Approve (files/annotates through the same gated Filer lane) or Dismiss; the sidebar Activity link carries an unreviewed-count badge. History rows stay undoable — including applied index rewrites.
- Settings → Brain: the trust ladder — Off / Suggest / Tidy / Organize (default Suggest), persisted and pushed to the daemon. Suggest applies nothing — journal proposals only, provably write-free on your notes. Tidy auto-applies annotations + filing brand-new captures; Organize applies everything — every rung journaled + undoable.
- ⌥A — summon chat (“ask”) — a new global chord: from anywhere, surface rotli and land in your most recently touched chat (or a fresh one). Rebindable like every action (Settings → Hotkeys → Chat).
Added — files & metadata
- Editable spreadsheets —
.xlsxand.csvopen in an editable grid (typed values + bold/text-color/fill styling, multi-sheet) when the file’s store is writable; a vault / linked-library / memex-storage/sheet keeps the read-only table. Explicit Save only (button or ⌘S — a binary rewrite never autosaves on keystrokes); the first save keeps a one-time.bakof the pre-rotli original beside the file (it shows up in Storage — that’s your escape hatch). Unsaved edits survive a tab switch (the dirty session parks in memory until you Save). Formula cells are read-only in v1 (styling them still works and never touches the formula). CSV is values-only and loads exactly — no type coercion (a007code or a 16-digit card number stays text), blank rows kept — with a one-click convert to .xlsx sibling when you want styles;xls/xlsm/ods/tsvstay the read-only viewer. Files over the 8 MB read cap (or the row/column caps) stay read-only — a truncated read can never be written back. - “Open externally” is a dropdown — default app · Reveal in Finder · installed “Open with …” apps (Numbers/Excel/Preview/TextEdit — only what’s actually on the machine, allowlist-gated in Rust so no caller-supplied binary ever runs).
- Show file metadata — a new toggle (Settings → General, or the note’s metadata panel):
the note’s raw frontmatter block renders at the top of the file — monospaced,
editable as plain text, exactly as it sits on disk. Commits ride a guarded lane that
restores the reserved
id/owner/createdkeys and refuses read-only notes; the metadata panel slims down to the Lock/Secure switches + Brain filing (the old key:value field editor is gone — the file itself is the editor now). - Drag ghosts everywhere — dragging a Main row (reorder and pull-in from the brain)
or a Board capture card now paints the same floating label ghost tab-dragging always
had: what you drag literally comes with you. One shared implementation
(
lib/dragGhost), pointer-events-transparent so drop hit-testing is untouched — and Esc / pointercancel now abandons those drags mid-flight, same as tabs.
Added — editor · search · viewers
- Full-text search, everywhere you type a query — All notes, the sidebar filter, the
palette picker, and Quick Note now search note bodies, not just titles, across the
whole searchable universe (staged captures + the brain + the Vault + added folders).
Title hits rank above body hits; a body hit shows a ±60-char snippet with the match
highlighted. Trash is the one place search never surfaces (Archive stays findable).
The ranking/snippet grammar is one pure core in Rust (
corpus_search) with a TS twin for the dev surface — mirrored test vectors keep them in lockstep, and offsets are char-counted so no emoji ever shifts a highlight. - **
html fences render** — same code ⇄ preview model assvg: the markup renders in a sandboxed, script-free iframe (verified against the shipped CSP — noallow-scripts, opaque origin; fence content is untrusted the moment a note is shared); click the block to see/edit the source. - Tables you can actually edit — inside a markdown table, Tab/⇧Tab hop cells (Tab past the last cell appends a row), ↑/↓ hop rows in the same column, Enter moves down instead of splitting a row (and exits below the table from the last row). The rendered table carries row/column menus — insert · delete · move · align — the slash menu inserts a fresh scaffold, and every op serializes back to ordinary padded pipes (a deliberate edit only; never a background reformat).
- Image zoom done right — an image opens at its natural size in points
(
naturalWidth ÷ devicePixelRatio, matching Preview — a small screenshot is crisp, not inflated), with a live % readout in the header. Click the readout for 100%, pinch-zoom or ⌘+/⌘−/⌘0/⌘1 after clicking the image, and scroll-pan when zoomed in. (This deliberately revisits “small images fill the pane” — crisp-at-natural won.) - Honest big sheets — a read-only sheet clipped by the row/column caps now says so
in a banner instead of silently showing a slice; an over-cap
.xlsxin a linked library refuses with a friendly message (not a zip error); sticky header row + column stay correctly layered under two-axis scroll, and a clipped read-only cell shows its full value on hover.
Changed
- Sidebar polish — the live filter now narrows Main too (it used to skip the one section you curate by hand) and matches snippets, not just titles — with the j/k roving cursor kept honest (it never lands on a filtered-out row). Main’s always-visible “+ New folder” row quieted down to a hover + on the section header (still Tab-reachable).
Fixed
- Main no longer forgets staged notes — Main, tab titles, and the row menu now read
the FULL note index (staged Captures + Archive + Trash + Vault), not just the default
listing. A staged note placed in Main used to vanish from the row and get GC’d out of
.rotli/main.jsonon the next save (the “seeded Main emptied itself / tab says Untitled” bug), and “Add to Main” on a staged note was a silent no-op. A Main ref now survives anywhere its file actually lives.
Notes
- Secure/locked are absolute: a
securenote (or one that merely looks secret) never enters any model — local included — at any trust rung; alockednote is never touched. That includes the edges: secure/locked notes are omitted from the generated_index.mdoverviews (a quick capture’s title is often the secret itself) and their title-derived filenames are kept out of the link-candidate lists sent to the model. Activity quietly counts skipped secret-looking captures for you to review yourself — a durable count that stays up across cycles until the capture is actually reviewed. The daemon is local-only: no web tools, nothing leaves the machine. - The daemon writes only through the contract-v3.7 Filer lane (
file_note/set_ai_field/write_index); your interactive write lane is byte-identical, and Main (.rotli/main.json) is structurally out of its reach. - Stale proposals retire themselves: edit a note after the daemon proposed something for it and the next pass dismisses the outdated row before proposing fresh — and Approve re-checks the note’s current state (moved note / user-edited field ⇒ it refuses instead of applying a stale decision). Journal rows carry the note’s ULID, so approving one proposal (which moves the file) never strands its siblings. Turning the ladder Off/down mid-run takes effect at the next note, not the next cycle — and a debounced settings save can no longer flip it back up.
[0.18.2] — 2026-07-01
A whole-codebase dead-code + consolidation sweep (three parallel audits: TS dead code, TS
duplication, the Rust shell) — less to manage, nothing user-visible lost. The Rust side came
back clean (no unused deps; write paths already share one atomic_write/relocate core).
Changed
- One menu system. The sidebar’s old keyboard row-popover (RowMenu) is gone; the m key now opens the same right-click menu, anchored under the row — so keyboard users get the FULL action set (Star, Add to Main, Rename…, File to the Brain, Archive, Delete) instead of the old three-item subset. The menu host gained first-item autofocus, ArrowUp/Down navigation, and hands focus back to the row on close. Right-clicking an archived/trashed note now correctly offers Restore (it used to offer Archive again).
- All notes + Recent are one component. The two content lists had grown as twins; both now
render a single
NoteListSurface(All notes = the searchable flavor). Same look, one file. - One Main drag. The “reorder Main” and “drag a note into Main” pointer gestures shared
their whole move/hit-test body — now a single
startMainDrag(mode)with two commits. - Shared
useBrainAreas()(the metadata panel and the right-click drill derived the area vocabulary separately) and oneinvalidateBothfor the lifecycle mutations.
Removed (dead code)
- The HTML5 note-drag dropzones in the sidebar (
NOTE_DRAG_TYPE/dropProps): nothing has started an HTML5 drag since the pointer-drag era — the handlers could never fire. (Moving a note is the ⊕/drag-into-Main gesture + Archive/Trash; a pointer-based move-to-folder can reuse the Main drag pattern when wanted.) - The retired
chatAllOpenbrowse state and the retired"chat"content view (chat is a pane). - Unwired wrappers + helpers:
chatComplete(the agenticchatMessagespath replaced it),showQuickWindow,memexInspect/memexListDir+ the service’sinspect/listDir,useCreateFolder,useMoveNote,addQuickNote,EMPTY_CONFIG, six unused glyphs, and the@types/katexdev-dependency.
[0.18.1] — 2026-07-01
Fixed
- Manual “File to the Brain” actually works now. A
.mdnote travels the app as its frontmatter ULID, but the Filer’s commands expected a file path — so the metadata panel’s filing section never recognized a staged note, and 0.18.0’s right-click drill never showed. Every filing entry point (set_ai_field/file_note/filer_move) now resolves through a ULID→rel bridge (newcorpus_note_path), the panel and menu detect staged notes by their real path, and the journal keeps recording paths for undo. Locked by a Rust test that files and un-files a note by its ULID. The right-click “File to the Brain” drill also appears on notes already in an area (re-file to another area).
[0.18.0] — 2026-07-01
A reported-issues sweep before Phase 4 (the organizer daemon): everything open from the left-menu / Quick-access / hotkey reports, resolved.
Added
- j/k keyboard nav reaches Main. The sidebar’s roving cursor now walks your Main rows (notes and folders, in your arrangement order) the same as the rest of the tree — j/k to move, Enter/l to open, h to collapse a Main folder, m for the row menu. Main notes ride with their own roving ids, so a note pinned in Main and visible in the Brain are two distinct stops.
- Contextual ⌘+ / ⌘− zoom. Zoom where you are: with focus in the sidebar it scales the whole section tree (persisted, clamped 0.8–1.4×); in a note it steps that note’s body-text size (the per-note Aa render layer — never written into the .md). “Reset zoom” is in the palette; all three are rebindable in Settings → Hotkeys.
- Right-click works on boards and tabs. A board row now opens the full context menu (Open in new tab · Add to Main · Rename… · Delete — Rename drops into the familiar inline input), and middle-click opens a board in a new tab like notes. Tabs got their own right-click menu: Rename… (boards and notes) · Close tab · Close other tabs.
- “File to the Brain” from the right-click menu. A staged note’s menu now carries the area drill (the 0.17.0 fast-follow) — pick People/Projects/… right from the row; same Filer gate + Activity journal as the metadata panel, one shared code path.
Changed
- Captures shows only real captures. A staged note you’ve curated — added to Main or ★ starred for Quick access — is a full note you keep, so it leaves the Captures board (and the sidebar count). Your “main note — seth” no longer poses as a sticky note.
Fixed
- Tab drag-reorder landed one slot right of the preview line (the hit-test counted the
dragged tab itself; audit CMP-1) — now it lands exactly where the line showed, locked by
a new
moveTabtest suite. - Row menus could overflow the window edge (audit CMP-4) — the sidebar row menu now clamps into the viewport and flips above its row near the bottom.
- A fresh Main folder ignored its first click — folders default open, but the toggle assumed closed; the first click now collapses as expected (keyboard h too).
[0.17.0] — 2026-07-01
Added
- Right-click context menu on notes. Right-click any note (in the Brain, a folder, Main, All notes or
Recent) for: Open in new tab · ★ Star / Unstar (Quick access) · Add to / Remove from Main ·
Rename… · Archive · Delete. Files get a slimmer menu (open / star / Main / delete). Built on a small
context-menu host + a shared
useNoteMenuhook, so every list wires it the same way; drill-in sub-lists are supported for future submenus. - Rename from the menu. “Rename…” opens a small dialog that rewrites the note’s title (its first line),
preserving a
#heading if it had one. (PurereplaceTitleLine, unit-tested.) - Open in a new tab without a modifier. Besides ⌘-click, middle-click a row now opens it in a new tab, and the menu’s “Open in new tab” does the same — build up multiple tabs by clicking, no need to make a blank tab first.
Notes
- Move-into-a-Brain-area from the right-click menu is a fast follow (it needs the note-id → path bridge the Filer uses); today, file a note into an area from its metadata panel’s File to the Brain.
[0.16.0] — 2026-07-01
Added
- All chats — a searchable list, the twin of All notes. Clicking All chats in the sidebar used to
just toggle an inline expand (and did nothing when you had only a few chats). It now opens a proper
content view: every chat in a searchable list, click a row to open it in a pane. (New
AllChatsSurface- an
allChatscontent view.)
- an
Changed
- Every pane surface fills its pane. Follow-through on the chat-centering fix: images, PDFs, spreadsheets, markdown, canvases and the activity log all render in a full-width pane body — no more content-width collapse.
Notes
- CSV & Excel render in-app. (Already built; now demoed.) A
.csv/.xlsxopens read-only as a table with a tab per sheet. Two sample files are seeded into Main to show it off.
[0.15.0] — 2026-07-01
Changed
- “Quick access” is now two things done right — Main + starred Quick access. The sidebar section is back to Main: your hand-picked notes, arranged your way. Quick access is now what it should be — a capped set (≤5) of starred notes that live in Main. ★ a Main row to star it; anything starred is what the ⌥ Quick window opens and cycles. Star / unstar any time; it layers on top of Main’s arrangement without moving anything.
Fixed
- Chat is really centered now. The prior fix centered inside the chat surface, but the surface
itself had no
flex: 1in the pane row — so it collapsed to its content width and pinned left, dead space on the right, and the internalmargin: 0 autohad no room to work. Every pane surface (chat, file, canvas, activity) now fills the pane, so the chat column truly sits centered.
[0.14.1] — 2026-07-01
Fixed
- Chat is actually centered now. The conversation was left-pinned once it had messages — a flex-item’s
default
min-width: autolet wide message content push the thread past itsmax-width. Switched to plain block centering (margin: 0 auto+min-width: 0), so the column is locked at its reading width and centered whether the chat is empty or full. - Only one chat row highlights at a time. “All chats” no longer stays selected while a specific chat is open — it lights up only when you’re actually browsing all chats (no chat active).
[0.14.0] — 2026-07-01
Changed
- Onboarding picks your theme first. The appearance step moved right after the welcome, so you set a theme you like before walking the rest of setup — no more trudging through it in one that hurts your eyes.
- Sidebar: “Quick access” + a collapsible Brain. The “Main” section is now Quick access — your hand-picked, most-needed notes (add with ⊕ on a note row, or drag one from the Brain). The Brain is now a collapsible row inside Destinations (its Activity link + areas fold away when you don’t need them).
- Captures look like sticky notes. The capture cards get a warm paper fill, real lift, and a slight hand-placed tilt — a board of sticky notes you can drag to arrange, not flat dark panels.
- Cleaner chat. Removed the divider lines (above the composer, under the header); the title now aligns to the same centered column as the conversation.
Fixed
- The quokka’s face reads again. The onboarding + empty-state quokkas were rendering with a heavy
stroke that filled in the eyes and nose dot — swapped to the original artwork (a clean
evenoddfill) recolored tocurrentColorso it still follows your theme. (The app icon was already correct.)
[0.13.0] — 2026-07-01
Added — Phase 3: manual filing + the Brain Activity log (see & undo the AI)
- File a note into the Brain, by hand. In a staged note’s metadata panel (the Aa chip → metadata),
a “File to the Brain” row lets you pick an area — the note files into
wiki/<area>/through the v3.7 Filer gate, and its open pane retargets to the new location. A filed note shows “🧠 Filed in .” - Brain Activity — a new pane (open it from Brain → Activity in the sidebar, or “Brain Activity →”
in the metadata panel) that logs every Filer action to
.rotli/brain-journal.jsonland lets you undo any of it: a filed note moves back, a set field restores. This is the trust surface — see and reverse every AI write before any of it becomes automatic (the background daemon is Phase 4). New Rustfiler_move+ journal append/read + asurfaceKind:"activity"pane;src/services/brainJournal.ts.
Changed
- Drag a note from the Brain (or any list) into Main. Cross-section pointer-drag: grab a note in the Brain and drop it into your Main view — before/after a row, or into a Main folder (the ⊕ still works too). Areas like People stay auto-maintained in the Brain; Main is your curated subset of individual notes, never a mirror of the areas. (Replaces the dead HTML5 note drag with the pointer pattern that works in the WKWebView shell.)
[0.12.0] — 2026-07-01
Added — contract v3.7: the AI Filer write lane (capability only, no daemon yet)
- The write-lane foundation for the background AI organizer (Phase 2 of the Main/Brain/daemon plan,
docs/design/main-brain-daemon.md). A second, narrower write actor — the Filer — may now write the curatedwiki/**brain (which stays read-only for you), gated separately from your own writes. Two actors, two gates, disjoint key-sets: you writechats/+_inboxand never the curated brain; the Filer writes the brain (area/summary/tags/links/…) and never your Main arrangement, and it refuses anylockednote. New Rustfiler_writablegate +set_ai_field(AI-keys-only) +file_note(fs-atomic filing move intowiki/<area>, preserving id, not bumpingupdated) +write_index(wiki/<area>/_index.md), mirrored incontract.ts(canFile/mayFile/AI_KEYS/USER_KEYS+ achats+inbox+fileperms tier only the daemon host runs with).owneris now reserved/immutable. - Nothing calls these yet — the manual “file this note” + journal/undo (Phase 3) and the Suggest
daemon (Phase 4) come next. The contract band extends to [3.4, 3.7]; we do not flip a brain’s
stored
memex.jsonversion (a 3.6 brain stays fully writable, so the Filer works today — the stored flip is a later coordinated step once Breve/voz ship). memex-vault’sSTRUCTURE.mdmoves to v3.7 in lockstep. Tests assert the two lanes stay disjoint (user closed towiki/**, Filer allowlist enforced).
[0.11.0] — 2026-07-01
Added
- Main — your hand-arranged view over the Brain. A new sidebar section above the Brain where you
arrange notes into your own folders and order, independent of how the AI files them underneath. It
holds no files of its own — it references your Brain notes by id, so it’s “one file, two views”
(edit a note in Main or in Brain, it’s the same file). ⊕ on any note row adds it to Main; drag
rows to reorder or move them into Main folders; + New folder makes a Main-only folder. Persisted to
a committed
.rotli/main.jsonso your arrangement travels with your memex. This is Phase 1 of the Main/Brain/daemon architecture (docs/design/main-brain-daemon.md) — the background local-AI organizer that keeps the Brain filed lands in later phases; because Main references notes by id, it will stay exactly as you set it while the AI reorganizes underneath. (The pinned Brain README + full drag-into- Main from other sections + j/k keyboard nav for Main are follow-ups.)
Fixed
- Images and PDFs use the pane. A small-resolution image (e.g. a Breve newsletter) no longer renders tiny at its natural size — it fills the pane (object-fit, so it scales up and stays readable); PDFs and the iframe fallback get a full-bleed block body instead of being shrunk by the centered layout.
[0.10.1] — 2026-06-30
Fixed
- Metadata panel no longer hangs on “Reading…”. Opening it on a secret-adjacent note triggers the
auto-secure-flag, which writes + updates
.gitignoreduring the read; 0.10.0’s security hardening made that write propagate errors, so any hiccup errored the whole read — and the panel had no.catch. The read-path auto-flag is now best-effort (still persists + logs; explicit “Mark secure” still hard-fails), and the panel surfaces the error instead of hanging forever. - Quick Note chord no longer occasionally opens the main window too. 0.10.0’s visibility guard had a
race — the spurious macOS
Reopencould fire before the panel registered as visible. Added a deterministic backstop: a summon timestamp stamped before the panel steals focus + a grace window in the reopen handler (belt and suspenders). - The Brain hides internal scaffolding.
_inbox(note staging — surfaced as Captures) and_templatesno longer appear as Brain areas (underscore-prefixed = internal, not user-facing). - The “Vault” (linked-library) destination is hidden until one is connected — an empty Vault row next
to your own
memex-vaultfolder was just confusing. It returns automatically when a second memex is linked.
[0.10.0] — 2026-06-30
Changed
- The Brain shows in the sidebar. Your AI-organized wiki areas (People · Projects · Research ·
Engineering · Theology · Reference) now render as a navigable Brain section under Notes — before
they were invisible (the sidebar never asked for the
wikifolder tree). Area labels are prettified. - One “Captures.” The duplicate capture concept is gone — there was a “Captures” row (under
Notes, read the
Boardfolder → always 0) AND a “Capture” destination (theInboxfolder). Now there is a single Captures under Notes: the defaultInboxshelf projects there, and the bottom “Capture” destination is removed. - ⌥C quick-capture lands in Captures. A quick capture is now a staged note in
wiki/_inbox/(it shows under Captures immediately) instead of appending toinbox.md(which surfaced nowhere). - “All notes” is a searchable list. Replaced the card grid with a clean list (title + date) and a full-width search; binary files (mp3/pdf/png/…) are filtered out (they live under Storage). Recent filters files too.
- Chat is centered + clean. The conversation column is now reliably centered (flex-center), matching the md editor’s reading measure.
- Storage organizes itself. The Storage section now groups your files — by Type (Audio · Images ·
PDFs · Documents · Other) by default, or by Date / by Folder via a new Settings knob (Location →
Storage). Computed in the frontend (
src/services/storageTree.ts); your files never move on disk.
Added
- In-app file viewers (universal). Clicking a surfaced file opens it in a right-pane file surface
instead of shelling the OS default app: audio gets a real player with a play button (no more Apple
Music), video/image/pdf render inline, text reads in-pane, and anything else falls back to an
asset
<iframe>preview + an “Open externally” escape hatch. Newfilepane surface (src/components/FileSurface.tsx) +corpus_file_text/corpus_file_bytesreads +media-src/frame-srcasset:in the CSP. - Spreadsheet viewer + chat review.
.xlsx/.xls/.csvrender as a clean read-only table (SheetJS, Apache-2.0;src/lib/sheets.ts). A newread_fileagent tool lets the on-device chat read a file by name (text, or a spreadsheet as CSV) so it can answer questions about it — look, don’t act.
Fixed
- The Quick Note chord opens ONLY the Quick Note. Summoning the floating note (⌥Q, or a rebound chord
like ⌥.) activates the app, which fired a spurious macOS
Reopen— and the main window came up too, defeating the whole point. The reopen now uses our OWN window-visibility check (the OShas_visible_windowsflag excludes thealwaysOnTop/skipTaskbarpanel), so the chord surfaces the floating note alone.
Internal (code-health pass)
- A codebase audit drove a cleanup. Hardened security:
gitignore_addnow propagates its write error (+ a symmetricgitignore_removewhen a note is un-secured); the web-egress secret guard keys offWEB_TOOLS. Removed dead code: the unwiredcaptureToInbox/inbox.mdchain (TS + Rust command + state + persistence), 5 orphaned memexinvokewrappers, the ~120-line pre-CodeMirror line renderer, thecontextWindowbudget override, and assorted dead exports. De-duplicated: onedateLabels.ts(5 drifting copies),openSummary()for open-by-kind (also fixes a file ⌘-new-tab regression),formatGlyphs,fileKind, Rust filename/id helpers (free_name/unique_id),forget_brain→forget_root, and cached web.rs regexes. Fixed: the broken Ctrl+2 chat hotkeys; 5 silent save-failurecatches now log. Net −25 lines across 49 files; all tests green.
[0.9.0] — 2026-06-29
Added
- The agentic memex client — Chat is no longer a context-free one-shot. The on-device model now runs
a multi-step tool-use loop over your memex (its knowledge base) and, opt-in per chat, the web:
search_notes/read_note— the model searches and reads your notes (their organization + metadata) to answer. Secure notes stay readable by the local model (the remote gate still holds).- Web search — DuckDuckGo, no API key — a per-chat globe toggle in the composer (off by
default) lets a chat reach the internet (
web_search/web_fetch); the model only uses it when your notes don’t cover the question. - Image attachment — a composer paperclip gated on a vision-capability check: only a vision-capable model accepts images; otherwise the UI prompts you to pick one.
- Engine lives in
src/ai/(host-agnostic — liftable to the shared~/.memex/aiclient layer), driving a tolerant single-JSON-object ReAct protocol tuned for Gemma; a live status line replaces the static “thinking…” (no token streaming yet).
- Web primitives in Rust (
src-tauri/src/web.rs) —web_search(DuckDuckGo lite + html fallback) andweb_fetch(HTML→text), both behind a secret-egress guard: a query/URL that trips the secret detector is never sent to the web. The detector is now shared (src-tauri/src/secret.rs) by the secure-note flag and the web guard. - Multi-turn model bridge (
chat_messages) — flattens the transcript for MLX/api/generate(with JSON coercion), or sends a real messages array to llama.cpp with the Bearer key (fixes a latent 401) plus image content-parts, and lazy-kickstarts the on-demand llama.cpp server. - Vision serving — gemma-3 is multimodal. Because the shared MLX server runs in a frozen py3.9 venv
(Breve’s) where the gemma3 mlx-vlm path can’t install, vision runs in an isolated py3.11 sidecar
(
~/.memex/ai/mlx-vlm-venv+mlx-vlm-server.pyon :11437); the text server proxies image requests to it and lazy-spawns it. The text path (mlx-lm) is byte-for-byte unchanged, so Breve/voz are unaffected. One-time setup:~/.memex/ai/setup-vision.sh.
Changed
- The Chat composer gained the globe (web) and paperclip (image) controls beside the model
selector;
chat_modelsand the memex-ai registry now carry avisioncapability (gemma-3 flagged).
[0.8.9] — 2026-06-29
Changed
- Chat is a centered modern column (ChatGPT/Claude style): the conversation + composer share a max-width and center in the pane; the model selector moved into the composer (bottom); AI replies render as plain text in the column, only your messages are bubbles.
- Tighter chat prompt — the on-device model answers only from the conversation and says “I don’t know” rather than inventing facts/file names (the earlier “Fabel 5… see STRUCTURE.md” was a small model hallucinating with no real context).
Fixed
- The welcome quokka’s face reads again — 0.6.3’s uniform
stroke-width:12had filled in the eye cutouts; dialedstays_localback to 4 (the body’s weight is the fill, so the face returns with minimal body change).
[0.8.8] — 2026-06-29
Added
- onboardingVersion gate — onboarding now re-runs reliably across updates. While
0.x(beta), every version change re-onboards (the flow is still evolving); once1.0, the bar freezes at1.0.0so updates never re-onboard — only a fresh install does. The build version is injected at compile time (__APP_VERSION__), persisted asonboardingVersion, and compared on launch.
[0.8.7] — 2026-06-29
Fixed
- Onboarding now requires choosing where rotli lives — no more silent
~/Documents/rotlidefault. The location step is required: “Skip setup” jumps to it, “Continue” is gated until you pick, and the third option is “Use a plain folder…” (choose a location) instead of a silent default. So every start is an explicit choice — use an existing memex · create a new one · or a plain folder.
[0.8.6] — 2026-06-29
Added
- Secure notes. A regex pass detects secret patterns (API/private keys, JWTs, SSNs, card
numbers) and auto-flags a note
secure: true— without recording the secret. A secure note’s content is never sent to a remote model (thecorpus_read_aigate refuses it; a local model like gemma may still read it), and its file is auto-gitignored so a pushed vault never leaks it. The metadata panel shows the flag with a manual toggle.
[0.8.5] — 2026-06-29
Added
- Opens maximized, and double-click the titlebar to zoom — the standard macOS gesture, re-enabled over the manual-drag titlebar.
Fixed
- Block-handle gutter no longer shows a light/white bar: the editor gutter is transparent, so the
+/ grip handles sit subtly in the left margin, theme-matched.
[0.8.4] — 2026-06-29
Added
- Move an inline image — drag the image itself to reposition it (it drops at the cursor line); resize stays on the corner grip, and a plain click still reveals the source.
- Editable metadata — the metadata panel’s fields (shelf/reach/area/tags…) are now editable: type a value (Enter/blur saves), × removes, the bottom row adds a field. Reserved keys (id/created/updated/pinned/origin/locked) stay managed by rotli.
Changed
- Chat is a pane surface now. A chat opens in a pane like a note or canvas — so multiple chats can be open at once, and a pane can hold a chat OR a note (note left, chat right). “New chat” / a chat row opens a chat pane; “All chats” expands the sidebar list; tabs/splits/ drag work on chats for free.
Fixed
- Chat UI rebuilt. Role labels (you · rotli), assistant replies render as markdown (bold/italic/code/links + fenced code blocks), a centered empty state, and a multi-line composer (⏎ send · ⇧⏎ newline). User-right / AI-left bubbles, the model selector intact.
[0.8.3] — 2026-06-29
Added
- Milkdown-style block handles — each block’s left-gutter handle is now a
+(add a block below) and a real 6-dot grip (drag to reorder · click for actions), replacing the lone⠿that font-fell-back to a thin white bar. - Real file-type logos — the sidebar, surfaces, palette, and tabs show the actual
monochrome format mark per file: the Excalidraw logo for canvases, the SVG logo,
the PDF (Acrobat) mark, and an IDE-standard picture glyph for raster images
(
currentColor, theme-aware; logo paths from simple-icons, CC0). - Board → Captures. The quick-captures view is renamed Captures; its cards are now
sticky notes (softly raised, lift on hover) that you can drag to reorder — the order
persists in
.rotli/settings.json, never in your notes. svgcode blocks render inline — a```svgfenced block shows the vector; click it to edit the source (the code ⇄ preview toggle), joining the existing math/mermaid/jsxgraph block renderers.- Inline images. Drag an image from Finder onto the editor → it imports into
storage/and drops in at your cursor as a cleanlink, rendered inline via the asset protocol. Drag the corner to resize (width stored Obsidian-style,); click the image to edit the source. Images dropped outside the editor still land in Storage. (Enables theprotocol-assetTauri feature + a scopedcorpus_absresolver.) - Metadata panel + AI lock. A button right of
Aaopens a panel showing the note’s frontmatter (id/created/updated + the AI-filled shelf/area/tags…) with a lock toggle — locking writes alocked: truefrontmatter line the eventual AI filer must respect (“don’t touch this note”). The line round-trips losslessly; the editor never sees it.
[0.8.2] — 2026-06-28
Added
- “Use as notes folder” on a connected brain — promote it to BE your notes folder, so a separate plain
~/Documents/rotlino longer lingers alongside it (the same folder can’t be both corpus and brain). - Non-note files surface in Storage. The walker only emitted
.md+.excalidraw, so the Storage folder looked empty; images/PDFs/any file now surface as a read-onlyfilekind that opens in the OS default app (kept out of All-Notes/Recent/Palette — they’re assets). Will evolve to route dropped binaries into the memexstorage/per the model.
Changed
- “brain” → “linked library” in Settings → Location: a connected memex is now a “linked library” (a
second memex you reference, tucked away) — freeing “brain” to mean your own AI-organized areas inside
Notes (per
docs/model.md). A rotli-created memex now scaffolds the gitignoredstorage/. - Removed the orphaned Memory front (dead code — nothing opened it); the brain is browsed via the Vault tree. Memory is how things are saved, not a front.
- Storage shows the memex
storage/. On a memex corpus the Storage front now surfaces the binary asset store read-only (opened in the OS default app), projected to the Storage destination — it was hidden before. - Drop a file to import it. Dragging a file from Finder onto the window copies it into the corpus’s
binary area (the memex
storage/, or localStorage/for a plain corpus) — collision-safe — where it shows in Storage and opens in the OS default app.
Docs
- Locked the rotli model + vocabulary (
docs/model.md) and realigned the always-injected.carlrules: three fronts (Inbox · Chat · Notes); “your notes folder is a memex”; “brain” = your AI-organized areas inside Notes (not a connected memex); a second memex is a “linked library”; Storage = the memexstorage/; access is metadata. Fixed a deadsmbrain-integrationpointer injecting a 404 every session.self/→identity/+personality/wording; “Settings → Memory”→“Location”; superseded banners onroadmap.html+ the v3.5 proposal + the rearchitecture doc.
[0.8.1] — 2026-06-27
Added
- Onboarding picks where your brain lives. The first-run Your brain step now lets you Use a
memex detected on this Mac, Create a new brain… (choose a folder — rotli scaffolds a fresh v3.6 memex
there and makes it your corpus), or keep just simple notes in
~/Documents/rotli. Whichever you pick, your one folder is your brain (or a plain notes folder if you defer). New Rustcorpus_init_memexscaffolds the v3.6 spine + a freshmx_memex.json; the choice commits once after onboarding, with theonboardedflag flushed to disk before the relaunch so first-run can’t loop.
[0.8.0] — 2026-06-27
Changed
- One folder = your brain: the corpus.json unification. Replaced four separate location
mechanisms (
corpus-root.txt,corpus-memex-root.txt,corpus-roots.json,memex-instances.json) with a singlecorpus.json— the notes corpus IS a memex by default (its folder is your brain), plus connected read-only brains and added folders. The active write target is the corpus when it’s a memex, else the active connected brain. A one-time migration preserves existing installs (and dedupes a brain that was double-registered as both a vault root and an instance — notes load byte-identically). - The Location pane is one folder. Collapsed to a single “Choose folder…” smart picker (a memex →
use it as your brain · an empty folder → move your notes there · any folder → use as-is) + Your brain
- Other brains / Connect a brain…. The four separate folder pickers, the “rotli sync” card, and
the Quick-capture toggle are gone — quick capture has one fixed home (the active brain’s
inbox.md, falling back to the Board only when there’s no writable brain).
- Other brains / Connect a brain…. The four separate folder pickers, the “rotli sync” card, and
the Quick-capture toggle are gone — quick capture has one fixed home (the active brain’s
- Memex contract bumped to 3.6 (numeric band
[3.4, 3.6]), matching memex-vault’sSTRUCTURE.md.
Fixed
- First-run onboarding can’t loop (the
onboardedflag is flushed to disk before the connect-brain relaunch); a note created into a memex corpus opens correctly (wire-id prefix derived from the active root); choosing/connecting an already-registered folder can’t open the same directory twice; “Check the brain” results show on the right card; a folder with only.DS_Storecounts as empty; brain perms are validated; a corruptcorpus.jsonis preserved as.bakinstead of silently re-migrated.
Docs
- Reconciled the always-injected CARL contract rule (v3.6 ·
identity/+personality/· the corpus.json model) and bannered the superseded design docs (memex-rules-first-pass.mdwrite boundary,next-stages.mdTrack 2).
[0.7.2] — 2026-06-27
Changed
- Settings simplified: Storage + Memory → one “Location” tab. The two overlapping settings sections collapsed into a single Location pane (the nav is now General · Hotkeys · Appearance · Location · Plugins), organized around the idea that your notes folder is — or can become — a brain (a memex): Your notes folder (storage medium · path · Reveal/Move) → Your brain (detect / connect / start a memex, per-instance perms, Browse in Notes, Check the brain) → The Vault (browse a brain alongside, read-only) → Quick capture. Pure UI re-composition — every control is preserved, with no data-layer or Rust change. First step toward “your corpus is a memex”; the onboarding folder-pick and the underlying root-model unification come next.
[0.7.1] — 2026-06-27
Fixed
- Block handles actually drag now. The handle used HTML5 drag-and-drop, which the macOS WKWebView
swallows — and a
draggableelement steals the click, so neither the drag nor the menu fired in the app. Rewrote the interaction with mouse events: drag the ⠿ to reorder (with a drop line), or click it for the menu. Both verified.
Added
- Tables are beautified. GFM markdown tables now render as real tables in the editor (bordered cells,
bold header, column alignment from the
:---:row, zebra rows). Put the caret inside and it reveals the raw markdown to edit — same live-preview model as fenced code. The.mdis untouched.
[0.7.0] — 2026-06-27
Two new features — block editing + external folders — plus the small-icon polish.
Added
- Block handles (Milkdown-style) — a toggle in the Aa panel (Blocks: Off / Handles). Turn it on
and every block gets a ⠿ handle in the gutter: drag it to reorder the block, or click it for
a menu — Add below · Move up · Move down · Delete. The
.mdstays the source of truth (every action is a plain text edit); off by default. Also reachable from ⌘K (“Toggle block handles”). - Add external folders — point rotli at any folder (e.g. a work folder) without moving it into your memex. The sidebar’s Notes section gains an “Add a folder…” row (and a Folders group for the ones you’ve added); the folder opens read-write in place so you browse + edit its markdown notes through rotli. The files are never copied or touched; a hover × forgets the binding (two-click confirm). rotli stays a notes app, not an IDE — only your markdown notes surface.
Changed
- Titlebar identity — just the quokka mark now, centered in the bar (no “rotli” wordmark).
- Bolder small icons — the menu-bar tray + titlebar quokka thicken only the body outline (eyes/ mouth stay crisp) so they read clearly at chrome size; the full-size art is unchanged.
- Memex contract band → [3.4, 3.6] — stays writable against the upgraded memex (
self/split intoidentity/+personality/+ the org layer); rotli’s own write surfaces are unchanged.
[0.6.3] — 2026-06-26
Changed
- Bolder quokka lines — the line-art quokka (logo, characters, icons) now draws with a thicker stroke, so it reads with more presence at every size.
- Refreshed app/dock icon — regenerated the full icon set (and the menu-bar mark) from the thicker-lined quokka, so the Dock icon has real weight.
[0.6.2] — 2026-06-26
Added
- Quokka accents in Settings — each Settings section (General · Hotkeys · Appearance · Storage · Memory · Plugins) now carries a small, muted line-art quokka at the top-right of its heading, matched to the section (Memory → the knowledge quokka, Storage → the stays-local quokka, …). Like the rest of the character set, the accent tints with the theme and stays a quiet flourish.
[0.6.1] — 2026-06-26
New brand: the line-art quokka. A warm, hand-drawn identity replaces the AI-generated art.
Changed
- New app icon — the quokka logo on a linen tile with black lines (clean and legible at every size). Regenerated the full macOS/iOS/Android icon set from it.
- New menu-bar icon — the quokka as a macOS template icon, so it tints to the menu bar automatically (black on light bars, white on dark) — the shape stays constant, the line color follows.
- New in-app logo — the titlebar identity is the quokka mark + rotli set in Baloo 2, the rounded wordmark face that pairs with the line-art character (self-hosted; Fontshare, commercial-OK).
- Quokka characters in the quokka-world surfaces — the empty state, the Chat connect state, and onboarding now show the hand-drawn line-art quokka characters (notes · chat · inbox · board · knowledge · local · base). Each is a single-path SVG that tints with the theme (the line color follows the active theme; the shape never changes).
Removed
- The old AI-generated quokka image (
assets/world/quokka-master.jpg) — replaced by the line-art set.
[0.6.0] — 2026-06-26
The left menu becomes the navigator — three sections, no more top dropdown (IA rework, Increment 1).
Added
- Three top-level left-menu sections: Inbox · Chat · Notes. The titlebar module dropdown is
retired — the sidebar IS the navigation now. Each section is a collapsible accordion (state
persists):
- Inbox = email — a clear placeholder of the intended structure (an All row + an
account accordion:
[email protected],[email protected], …, thread sub-accordion later). The mail integration is a later increment; rotli writes nothing for it. - Chat — a ChatGPT-style section over your memex
chats/: + New chat, a searchable All chats, and your recent history (a limited view; “All chats” opens the full search). Clicking a chat opens it in the content area beside the sidebar — Chat is no longer a full-surface front reached from a dropdown. - Notes — the corpus, unchanged: All notes · Board · Recent, then the local destinations, the Vault/Knowledge folders, and nested folders. (Memory isn’t a section — it’s simply your Vault.)
- Inbox = email — a clear placeholder of the intended structure (an All row + an
account accordion:
- Pick the chat model from your memex AI. The Chat surface has a model selector that reads
the shared on-device store (
~/.memex/ai/registry.json) and lists every chat-capable model it declares (Gemma via MLX, the llama.cpp backup, …), defaulting to the store’s default. The bridge now speaks both wire shapes — Ollama/api/generate(MLX) and OpenAI/v1/chat/completions(llama.cpp) — so the picked model actually runs. The choice persists.
Changed
- “Inbox” now means email; the note-capture concept is “Capture.” The local capture destination
(and the ⌥C one-breath capture) is labeled Capture so the word “Inbox” is free for mail. The
on-disk name and the memex contract are unchanged (
inbox.mdkeeps its name; rotli still writes onlychats/,inbox.md,wiki/_inbox/). - The titlebar identity is now a plain rotli home wordmark (click → back to the note panes).
(Increment 1 is the structural left-menu rework only. Streaming chat, @note/@board/@email
context, the chat-owns-a-summary-note model, Breve history/ rendered in Chat, and the real email
integration are later increments. Plan: docs/notes-chat-inbox-rearchitecture.md.)
[0.5.0] — 2026-06-26
The Chat front begins — a real on-device chat (Increment 1).
Added
- Chat actually talks now. The Chat front (module switcher → Chat) is a real conversation:
type a message and the on-device model replies — the same local MLX/Gemma server Breve uses,
bridged through Rust (the webview’s CSP can’t reach
localhost, so achat_completecommand POSTs the model). Messages render as bubbles; the thread persists aschats/<slug>.mdin your memex (rotli’s owned surface, v3.5 contract) and reloads from there. The left list is your history. Needs your local model running on:11435; if it’s not, the chat says so in-line. (Increment 1 — one-shot replies, no streaming yet. Next: streaming ·@note/@board/@emailcontext · the chat-owns-a-summary-note model · Brevehistory/rendered in this surface · the 3-section left menu. Plan:docs/notes-chat-inbox-rearchitecture.md.)
[0.4.3] — 2026-06-26
Added
- Rename a board from its tab, too — double-click a board’s tab to rename it inline (joins the sidebar right-click rename from 0.4.2; both share one flow). And ⌘⇧N makes a new board (⌘N stays new-note), opening it straight into its name field.
- Board metadata for the AI — each board now carries a description + tags via a small ⓘ
button (bottom-right of a board). A board is just an image to a text LLM, so this is how it’ll know
what a board is about and pull it into a chat as
@boardcontext later. Stored top-level in the.excalidrawfile (not Excalidraw’s appState, which it strips) and preserved across drawing edits. (Wiring it into rotli’s own ⌘K search arrives with the Chat front.)
[0.4.2] — 2026-06-26
Added
- Name and rename your boards. A new board’s sidebar row opens an inline name field
the moment you create it (name it first, no more “untitled”), and right-click any board
→ rename in place (Enter commits, Esc / click-away cancels). The
.excalidrawfile is renamed on disk and any open canvas tab follows the new name. (Newcorpus_rename_board, unit-tested.) (Renaming via the tab, a dedicated new-board chord, and board metadata for AI search are the next step.)
Fixed
- The sidebar’s right-click no longer pops the webview’s “Reload” menu — it’s suppressed in the sidebar so rotli’s own row actions take over (the editor keeps its native menu for spell-check / copy).
- The Vault repopulates after the memex move (0.4.1’s self-heal) — if your Vault still
reads empty, Settings → Storage → Connect a folder →
~/memex-vault.
[0.4.1] — 2026-06-26
Fixed
- The Vault no longer goes empty after the memex move — an installed app had its Vault
bound to the now-gone
~/smBrain; that dead binding was dropped without rebinding, so the Vault showed nothing. It now self-heals to~/memex-vault(a vanished bound path re-auto-binds to the default memex; an existing-but-non-memex folder is still left alone). - The note header status is back at the top-right — centering the header had stranded the
chars · updated · On this Mac · Aacluster mid-pane with a gap. The header is full-width again (date left, status right); the body column stays centered.
Changed
- Notes use a bit more width by default (comfort measure 720→820px) so a note fills more of a wide screen.
- Recent reads as a clean table — hairline row separators + roomier rows + clearer title/snippet/date columns.
- New Excalidraw boards open in your color theme (dark or light), instead of always-light.
[0.4.0] — 2026-06-26
The memex-vault + polish release — the connected brain is renamed memex-vault (with an
internal storage/), and a round of UI fixes: centered notes, a dated Recent list, the
Vault’s wiki reframed as “Knowledge”, Settings-on-General, and two interaction bugs
(the Quick Note hotkey, and a board tab trapping note-clicks) put right.
Fixed
- A note no longer hugs the left on a wide screen — the writing column is centered and a touch wider (comfort measure 660→720px, default size 14.5→15px), so a note fills more of a big display instead of stranding dead space on the right. The date/status header aligns to the centered column.
- Opening a note while a board was open is no longer a dead click — replacing a canvas
(Excalidraw) tab kept
surfaceKind:"canvas", so the pane stayed stuck on the board and every sidebar note-click did nothing (and a note could look blank).openNotenow swaps to a clean note tab. (Fixes the “stuck on the board / blank note” reports.) - The Quick Note hotkey only controls the Quick Note — closing it (its chord / Esc) no longer surfaces the main window; if you came from another app it steps out cleanly instead.
Changed
- Settings opens on General (was Hotkeys).
- Recent is a dated list — every note ordered by most-recently-touched, shown as rows with the date on the right (title · snippet · date), in the content area.
- The memex
wikireads as “Knowledge” in the Vault, with a plain-language note (on hover) that it’s AI-organized for retrieval; the_templates/_inboxplumbing folders are hidden from the tree. (A toggle to reveal the AI metadata on a note is still to come — it’s stripped at the read layer today.) - The connected memex is now
memex-vault(wassmBrain). The maintainer’s brain moved to~/memex-vault(repoSethMed7/memex-vault) to read as what it is — a private instance of the open-source memex structure. rotli’s auto-bind default and all references follow it; thevault:root scheme and the Vault UI label are unchanged. A memex’s binaries now live in an internal, gitignoredstorage/(thestorage:root), so a connected memex is one self-contained folder. (No corpus migration — rotli keys the Vault by root name, not path; re-point it in Settings → Storage if you’d bound the old path, or rebuild so the new~/memex-vaultdefault auto-binds.)
[0.3.0] — 2026-06-25
The memex release — rotli now reads, writes, edits, and creates notes inside a connected
memex (your ~/memex-vault) per the v3.5 note contract, plus the Vault, Excalidraw boards,
nested folders, and inline diagrams/math from the increments since 0.2.2.
Added
- Notes show by your folders, not the brain’s filing (memex integration, Phase 2 —
shelf-projection, read side) — a note in a connected memex now appears in the sidebar
under its
shelf:(the folder you put it in), never its disk path. So a note rotli staged intowiki/_inbox/withshelf: [Inbox]shows under Inbox; one filed toNorthstar/Paymentsshows there — and you never feel it physically lives inwiki/. Thewiki/_inbox/staging dir is hidden from the tree (it’s plumbing); curated notes that don’t carry a shelf yet keep showing under their wiki area until one is set. Frontmatter stays hidden (it always was). - Edit memex notes in place (memex integration, Phase 2 — editability) — a shelf-projected
memex note now opens and saves like any rotli note: edits write back to its
wiki/_inbox/file with the v3.5 frontmatter preserved (owner/area/summary/tags/links/shelf/reachride through untouched) andupdated:bumped to aYYYY-MM-DDdate (memex notes stay date-shaped; local notes keep rotli’s timestamp). Memex date stamps are now honored for sort order too. - New notes default into your memex (memex integration, Phase 2 — creation flip) — when a
writable memex is connected, ⌘N and + New note create the note INTO the memex’s
wiki/_inbox/staging (v3.5 contract) instead of the local Inbox, and open it. An explicit LOCAL folder selection is always respected (never diverted); a selected shelf folder seeds the new note’s shelf. (Quick Note still captures locally — a follow-up.) The sidebar still shows these under the memex’s shelves nested in the Vault row; promoting those shelves to the primary top-level view (local demoted to a collapsed section) is the remaining visual step. - Write notes into your memex (memex integration, Phase 1) — Memory now has a
+ Note button (when the connected memex is writable for rotli). It writes a
brand-new note into the memex’s
wiki/_inbox/staging area following the v3.5 note contract: a hidden frontmatter block (id·owner·created/updated·shelf·reach) wraps your plain-markdown body, with the AI metadata (area/summary/tags/links) left blank for a later local-LLM pass to classify and file. The note round-trips memex-vault’s ownvalidate.tscleanly. This begins retiring the “notes always land in the local Inbox / Vault read-only” interim — the Vault sidebar browse stays read-only; the explicit write lives in Memory for now. rotli still writes onlychats/,inbox.md, andwiki/_inbox/— the rest of the brain is refused at both the TS gate and the Rust guard. (rotli now speaks the memex contract band [3.4, 3.5], so a~/memex-vaultwhose card still reads3.4stays writable.) - The Vault (multi-root corpus) — the old “Brain” destination is now Vault
and points at an external memex (your
~/memex-vault), browsed in place in the sidebar (itswiki/+chats/, read-only) alongside your local notes. Connect one in Settings → Storage → “Connect a folder…”. rotli never writes your notes into it —chats/is only the chat area, and new notes always land in your local Inbox. Folder ids gained aroot:pathscheme (local ids stay bare, so nothing migrates); each root gets its own file-watcher. - Diagrams & math in your notes — fenced
```math(KaTeX),```mermaid, and```jsxgraph(interactive plots — sine waves, unit circles, draggable points) now render inline in the editor. They follow your theme, show an Expand button, and reveal their raw source when you click/caret into them (your.mdkeeps the literal fenced source — it’s a render layer, never a rewrite). Bad input shows a tidy error box instead of breaking the editor. - Excalidraw boards — a board is a real
.excalidrawfile living in your corpus folders next to your.mdnotes (a file you own, openable in excalidraw.com). Boards open in a pane like a note, save to disk as you draw, and show in the sidebar with their own glyph. Excalidraw is code-split, so it loads only when you open a board. - A
+menu in the sidebar (replaces the pencil) — New note · New Excalidraw board · New folder. - Nested folders — create a folder inside any folder (e.g. an
excalidrawfolder inside Inbox) from the+menu. The inline name commits on Enter or when you click away (Esc cancels). - Per-section
+— hover any section (Inbox / Brain / Storage / a folder) and a+appears where the count was: one click drops a new folder inside that section. Plus a collapse-all button in the sidebar header.
Changed
- Board and All notes now open as grids in the content area to the right of the sidebar — the sidebar no longer disappears, and there’s no empty pane. Board stays a home for quick captures; All notes adds a search box and shows every note (and board) as cards. Clicking a card returns to the editor/canvas.
Fixed
- The editor now keeps the caret above the floating format bar while you type — the last line pushes up instead of sliding behind the bar.
- The Quick Note hotkey (⌥Q) now controls only the Quick Note: closing it returns you to where you came from and never surfaces the main window.
- The Quick Note header is draggable again — the title is a centered button with draggable space on either side, so the window is easy to move.
[0.2.2] - 2026-06-24
Added
- Copy as you see it: copying from the beautified editor strips markdown syntax —
no
**around bold, links become their text, list/heading prefixes dropped. - A Beautified ⇄ Raw markdown view toggle in the Aa panel — read your notes as live WYSIWYG or as the plain markdown source (the file is identical either way).
Changed
- Tidier bullet / numbered lists: a tighter hanging indent and a centered marker, so the glyph sits next to its text instead of adrift at the far left.
[0.2.1] - 2026-06-24
Added
- A quiet “update available” dot on the titlebar Settings button, so a new release tells you it’s here without a badge or a ping. The check now also re-runs when you summon the app and on a slow timer (still silent — no auto-download, no modal).
Fixed
- Auto-update could fail to unpack (
failed to unpack ._rotli.app): the updater archive is now built withCOPYFILE_DISABLE=1so macOS doesn’t add AppleDouble sidecar files the unpacker rejects.
[0.2.0] - 2026-06-24
First public release — a warm, local-first menu-bar notes app, now with a memex brain and signed auto-updates.
Added
- memex integration — rotli can read/connect/initiate a memex knowledge spine
(for the maintainer,
~/memex-vault): a read-only Memory browser overwiki/self/chats, a Chat front that writes namedchats/conversations, ⌥C captures that route to the brain’sinbox.md, and “Browse in Notes” to make a memex the corpus. rotli ownschats/+inbox.mdand never writes the brain’s memory. - CodeMirror 6 editor — inline WYSIWYG markdown (syntax hidden, revealed on the caret line), live preview, focus mode, and a fully rebindable keymap.
- Signed in-app auto-update — a quiet on-launch check + a manual “Check for updates / Install & relaunch” in Settings → General (no auto-download, no nags).
- The menu-bar shell — ⌥Space toggle, ⌥C one-breath capture, ⌥Q Quick Note, the Board, onboarding, and a local-file corpus (atomic writes, OS-trash deletes, external-edit watcher). Developer-ID signed + notarized.
Release tooling
bun run build:mac,bun run release, and thebump-version/predmg-clean/make-latest-jsonscripts.
[0.1.0]
Added
- memex integration (Increments 1–3): detect/connect/init a memex instance, the read-only Memory browser over its spine, chats/ + inbox.md write seam, and “Browse in Notes” to point the Notes tree at a memex.
- Editor rewritten on CodeMirror 6: inline WYSIWYG markdown (syntax hidden, revealed on the caret line), live preview, focus mode, and the shared keymap.
- Onboarding flow, the Board surface, and the Quick Note window (⌥Q) with the ⌘P quick-note picker.
- The menu-bar shell: ⌥Space main toggle, ⌥C one-breath capture, the local-file corpus (atomic writes, OS-trash deletes, an external-edit watcher), and a fully rebindable hotkey engine.