← Back to MindOS

Changelog

What's new in MindOS. Current version: v0.5.11

    • Added the e2e tests I should have shipped with v0.5.2. Two Playwright specs exercise the drag-and-drop reorganization end-to-end: one drags a page onto a folder header, verifies both the file moves on disk AND the sidebar link href updates (watcher → refresh); the other drags into the root drop zone from root, verifies zero server calls (correct no-op). Both pass. 6/6 e2e overall.
    • Cursor feedback on draggable items: `cursor-grab` on hover, `cursor-grabbing` while actively dragging. Fixes the "it doesn't look draggable" feel — there was no visual cue that sidebar pages were pickupable.
    • Drag-and-drop page reorganization in the sidebar. Grab any page and drop it on a folder header to move it there. A "drop to move to root" zone appears at the top while you're dragging. Uses @dnd-kit (keyboard accessibility baked in — space to pick up, arrows to navigate, space again to drop).
    • New backend action type: `move`. Renames the .md file on disk (with cross-device fallback), refuses to clobber an existing destination, returns 404 if the source is missing. Covered by 5 new unit tests.
    • The UI piece was drafted by Gemini 3 Pro — drag-and-drop has enough edge cases (collision detection, keyboard coords, pointer activation distance to not block clicks) that it pays to hand that specific task to a model that's tuned for spatial React code.
    • Fix: sidebar now refreshes when a page is renamed/edited. ContentWatcher was skipping router.refresh() on /w/* routes to avoid stomping WikiView's state — but that also meant the layout (which renders the sidebar) never re-ran. Now it always calls router.refresh() AND dispatches the custom event; client views preserve their state, server trees pick up fresh data.
    • Action card rewrite: the terse "EDIT test +27 −2" is gone. Every tool call now includes a required `description` field — one plain-English sentence like "Rewrite the intro as a satire" or "Split Examples into its own page". That's the card's primary label; verb + slug + diff counts fall to a secondary metadata line.
    • System prompt updated to enforce descriptions. Cards are now scannable — you can tell three stacked edit proposals apart at a glance.
    • Architectural fix: wiki pages now render client-side. Was a Next.js server component going through ten cache layers (wiki cache, RSC cache, route cache, HTTP response cache, Chromium memory cache). Now it's a thin React component that fetches /api/page/:slug on mount and re-fetches on any file-watcher event. React re-renders in place. No reload, no navigation, no caches to invalidate.
    • After an AI Apply, the page updates instantly — the write is immediately visible with zero round-trip through Next's rendering pipeline. The entire class of "apply doesn't refresh" bugs is now structurally impossible.
    • Unified content-change signal: one custom window event (`mindos:content-changed`) carries the notification across all sources — Electron's chokidar watcher via IPC in packaged builds, the SSE dev watcher in browser preview. Client views subscribe once and react regardless of environment.
    • Manual refresh button now calls the WikiView's refetch directly (cheaper, cleaner) instead of a full document reload. Still falls back to reloadIgnoringCache when there's no view handler.
    • Playwright e2e suite passes 4/4 against the new architecture — including the specific scenario of "apply happens, no user-initiated reload, verify new content is visible within seconds".
    • Fix the apply-stays-stale bug at the actual root: the wiki cache is now invalidated BEFORE the disk write, not after. Previously the file watcher fired on the write, triggered a renderer reload, and that reload hit Next.js while the cache still held the old pages. Plus an optimistic client-side DOM swap for same-page edits — you see the new content instantly, no waiting for the server to re-render.
    • Stop button: while the AI is streaming, the Send button turns into a red Stop. Clicking aborts the in-flight request immediately (AbortController was already wired; just needed UI).
    • Model autocomplete from the provider itself: OpenRouter's 300+ model catalog is fetched from their /models API on mount, Ollama's locally-installed models come from /api/tags. You can type or pick anything; curated shortlist still surfaces at the top.
    • Manual refresh button in the page header (circular arrow next to the breadcrumb). Escape hatch when every other refresh path fails — forces a cache-busting reload.
    • Architectural: AI edits now use provider-native tool calls (edit_page, create_page, delete_page) instead of regex-parsed ```action fences. Claude 4.6/4.7, GPT-5, Gemini 3, and Ollama (gemma4:26b, qwen3-max) all support tools natively — the model sends structured JSON, we dispatch it directly. No more truncation mid-fence, no more hallucinated slugs: the schema constrains the call shape at the provider level.
    • Backward compatible: if a model still emits ```action blocks (older local models, non-tool-capable providers), the fence parser keeps working as a fallback alongside the tool-call path.
    • System prompt rewritten: shorter, instructs tools as the primary surface, mentions action-fences only as a "last resort".
    • Tests: 11 new cases for lib/tools.ts (parseToolCall, wire-shape conversions, ParsedAction bridge). 50 total pass.
    • The AI now gets an explicit list of pages that actually exist on disk in its system prompt — it stops proposing edits to pages that were never written (e.g. after a truncated create).
    • "page not found" on Apply is now recoverable: the review pane header shows a Create instead button when an edit lands on a missing slug. One click converts the action to create and applies it.
    • Page list auto-refreshes on any content change (file watcher event), so the AI stays grounded even after you reorganize your folder.
    • Fix: action cards no longer stuck on "streaming…" forever when the model ends mid-fence (context limit, network drop, Ollama stall). The chat now threads a live-streaming flag into each card: still coming in → pulsing "streaming…"; stream ended without a closing fence → red "truncated" tag. Review stays disabled in either case so you never apply a half-finished body.
    • Parser tests: four new coverage cases including end-of-stream without a trailing newline, a truncated header-only block, and a mixed finished+truncated pair. 39 tests pass (+4).
    • Fix: Apply now always shows the new content. location.reload() was getting served a stale response by an upstream cache for some users; switched to a cache-busting URL (?t=timestamp) that Chromium treats as a fresh navigation.
    • Motion: after Apply, the article now fades up + a thin accent bar sweeps left-to-right across the top of the page, so you see the swap happen instead of wondering if anything changed.
    • Action cards now show a diff summary next to the slug (+12 −3, etc.) — three "EDIT test" cards stacked in the chat are finally distinguishable at a glance.
    • Action cards animate in (gentle fade-up, 180ms) when the AI emits them, feels less like a paste.
    • Chat accepts images. Click the paperclip, drag-drop onto the chat panel, or just paste from clipboard. Up to 8 images per message (8 MB each), shown as thumbnails above the input with individual ✕ remove buttons.
    • Images are routed per-provider as multimodal content: inline base64 parts for Gemini (AI Studio), image_url parts for OpenRouter (works with Claude, GPT-5, Gemini 3 Pro, any vision-capable model), and Ollama's native images[] field (works with qwen3-max, gemma4, llava variants).
    • In-message thumbnails stay in the conversation afterwards so you can scroll back and see what you asked about.
    • Chat history persisted to localStorage drops images — only kept in-memory for the current session — to stay within the browser's 5 MB quota.
    • Fix (for real this time): Apply on an AI edit now reloads the page — v0.3.1 was using location.href = current path, which is a no-op in Chromium when the URL doesn't change. Swapped to location.reload() for edits; create still navigates to the new slug, delete goes home.
    • Action cards latch once resolved: after Apply or Discard, the card stays as "✓ Applied" / "Discarded" instead of re-offering the Review button on re-renders.
    • Chat panel is now a side-by-side column (Linear / Cursor style), not a fixed overlay. Opening it reflows the page into the remaining width; closing animates it to zero. No more content hidden under the chat.
    • Page area now scrolls internally inside <main> rather than the whole document. Sticky sidebar stays truly sticky.
    • Tests: added lib/diff.ts coverage (hunk generation, line numbers, word-level token pairing, multi-hunk totals). 35 tests pass.
    • Fix: AI configuration (provider, model, chat history, sidebar collapse state, theme / language) no longer resets on every launch. Root cause was the dynamic port — localStorage is origin-scoped and the port is part of the origin, so a new port each launch meant a new origin and empty storage. Now binds a stable port (50645) with fallback to a free one only on conflict.
    • Live file watcher: any .md file added, changed, or removed inside your content folder — by MindOS, vim, iCloud sync, git pull, whatever — reloads the current view within ~200ms. External edits no longer require an app restart.
    • Fix: applying an AI edit now always shows the result (was stuck on stale content in v0.3.0 due to a router-refresh quirk). Apply triggers an explicit re-navigation, and the file watcher belts-and-braces the refresh.
    • New AI review pane: clicking "Review →" on an edit/create/delete card swaps the document area for a full-width diff view (GitHub PR style). Chat stays pinned to the right — the page fades underneath.
    • Diff rendering: hunk-based with ±3 context lines, old/new line numbers, and word-level highlighting inside changed lines (you see the exact bytes that moved).
    • For `create` actions the pane renders the new page's markdown preview. For `delete`, the current page with a red overlay + where it's going in `.trash/`.
    • Keyboard: <kbd>a</kbd> apply · <kbd>d</kbd> discard · <kbd>esc</kbd> back. Apply animates with a brief green flush before closing.
    • Chat's action card is now compact — one line with the slug and a "Review →" button. Apply/Discard moved to the pane header so there's only ever one surface to act on.
    • Fix: auto-updater now actually works. The electron-updater package was missing from the bundle in v0.2.0 → v0.2.3, so "Check again" was silently doing nothing. It's properly in dependencies now and included in the ASAR. This is the one manual re-download — every release from here lands by itself.
    • Hardened the updater load path: if the dep is ever missing again, the UI shows an error state instead of staying stuck on "Up to date".
    • Sidebar reshuffled (Linear-style): removed the redundant "MindOS" header (window title already says it), footer becomes three stacked rows — big "+ New page" with ⌘N, search with ⌘K, then a compact icon strip (update dot · settings · reveal in Finder) with the page count.
    • New ⌘N shortcut opens the New page modal from anywhere.
    • Update dot becomes icon-only (hover / popover for details), matching the rest of the footer icon strip.
    • Fix: the Next.js server subprocess no longer shows as a separate "exec" tile in the macOS Dock. Switched from spawn(process.execPath) to Electron's utilityProcess.fork, which uses the Helper binary (LSUIElement: true).
    • Updater UX polish: amber dot for "update available", emerald for "ready to restart". Release notes render inline in both the toast and the sidebar popover.
    • Toast remembers dismissals per (state, version) — dismissing the "available" prompt doesn't suppress the later "ready to restart" one.
    • Trimmed the sidebar header (removed the "your mind in markdown" tagline — it's already in the window title).
    • Model suggestions refreshed: Qwen 3 Max + Qwen 3 Coder added on Ollama and OpenRouter. Claude Sonnet 4.6 is the default on OpenRouter.
    • Auto-updates — MindOS now polls for new releases in the background and offers Restart when one is ready. No more manual re-downloads.
    • API keys moved to Keychain (macOS) / libsecret (Linux). Previous localStorage keys are migrated on first launch, then wiped.
    • Download page rewritten: OS-detected primary CTA, trust signals inline, version chip.
    • Version label on the marketing site so you can see what's shipped.
    • Installed app correctly reports its own version (was stuck on 0.1.0).
    • CI hardening: signed/notarized Mac DMGs land on the VPS reliably.
    • Titlebar always reads "MindOS" (was echoing page H1s including 404s).
    • Fix: 404 after creating a new page — wiki cache now invalidates on write.
    • Real not-found page with recent pages + new-page CTA.
    • Chat panel no longer framed as "about this page" — works on any screen, understands create as a first-class action.
    • ⌘K is a full action palette (new page, toggle theme, export, import, reveal in Finder, …).
    • Sidebar: sticky root section headers, tooltips on truncation, accent-tinted active item.
    • Initial public beta: wiki, ⌘K search, AI chat (Ollama / AI Studio / OpenRouter), action cards with Apply/Discard, ⌘⇧C chat toggle.
    • New-page modal with title / folder / tags.
    • Content folder picker + export + import + reveal in Finder.
    • Light / dark / auto theme, English + French UI.