OpenKnowledge

v0.49.0

Released Aug 7, 2026. Part of the OpenKnowledge changelog.

Minor Changes

  • Comment on mermaid diagrams, math, images, wiki links, and tags.

    Commenting on ordinary prose failed with "The quoted passage is not in the document" whenever the paragraph merely contained a highlight, an image, a wiki link, a tag, inline math, a footnote marker, an underline, or an autolink. In a wiki-style document that is most paragraphs, not an edge case, so a comment on a normal sentence often just produced an error and was lost. Each of those constructs spends characters on markup that renders as less than it spells, and the anchor matcher only knew how to look past some of them. It now looks past all of them, including an aliased wiki link's hidden target and a link's heading fragment.

  • OpenKnowledge now speaks your language. On first launch it follows the language your operating system is set to, and Settings → Appearance → Language lets you choose a different one at any time. The switch is immediate — the interface, the native File/Edit/View menus, and the app's dialogs all change while you keep working, with nothing to restart and nothing to reload.

    Eleven catalogs ship: English, Simplified and Traditional Chinese, Spanish, Hindi, French, Arabic, Bengali, Brazilian Portuguese, Indonesian, and Urdu. Three are offered in the picker today — English, Español and 简体中文 — because a language appears there once someone who reads it has reviewed it. The rest are complete and reachable by name, so a translator can run the app in the language they are checking; Arabic and Urdu stay reachable but unlisted until right-to-left layout lands.

    Detection is script-aware rather than a language-code match, so a Traditional Chinese system in Taipei gets Traditional rather than Simplified, and es-MX gets Spanish rather than falling back to English. Choosing System keeps following your OS from then on, including if you change it later — the choice is stored as "system" rather than as whichever language that happened to mean the day you picked it.

    Your own writing is never touched. Document text, titles, file and folder names, frontmatter, tags and link targets stay exactly as you wrote them, in whatever language you wrote them in; only the application's own chrome changes.

    For anyone adding UI copy: strings are extracted and translated in the same change, and a lint rule now fails the build on a new hardcoded user-facing string, so a missing translation is caught before it ships rather than discovered in the interface.

  • A markdown document can now be opened as a slide deck in its own OpenKnowledge window, via a new Slidev plugin (beta). Rendering is handled by Slidev, which OpenKnowledge neither renders itself nor downloads or bundles — so install it first: npm install -g @slidev/cli @slidev/theme-default (global), or add those packages to the project (a project-local install takes precedence). Slidev themes ship as separate packages from the CLI, and a deck cannot open without the theme it declares — @slidev/theme-default covers decks that use the default theme or declare none.

    Then turn on the Slidev plugin in Settings → Plugins, add slides: true to a document's frontmatter, and an Open in Slidev action appears in the editor toolbar; activating it opens the deck in a dedicated window you can present from. Editing the document in OpenKnowledge updates the open deck, because Slidev watches the file OpenKnowledge is already saving to.

    The plugin's own settings page reports whether OpenKnowledge found Slidev, and offers the install command to copy or to run in a terminal when it did not. When no slidev resolves, the toolbar action is simply absent rather than failing on click. Closing a deck window stops that deck's process, and quitting the app stops all of them. The plugin is off by default, desktop only, and adds nothing to the app bundle for anyone who does not enable it.

    Docs: Plugins → Slidev.

Patch Changes

  • In-app agent (ACP) reliability overhaul from the July 31 bug bash. Startup failures now tell the truth: "sign in first" only appears for real authentication failures (classified by the protocol's auth-required code), other errors show the agent's own message with wire-level details behind a Show details disclosure, and failed threads keep their transcript instead of erasing it when the tab closes. Sign-in works in place — auth failures render a button per advertised sign-in method, and completing one reopens the session on the same agent process with your drafted message intact. Agents and their terminals now inherit your login shell's PATH on every launch (not just when the top-level command is missing), so tools installed via nvm and friends resolve; a Retry button on failure notices re-probes the PATH and respawns. Queued messages survive Stop (they fold back into the composer), editing a queued message holds it until you resubmit, the queue says when it delivers, and a new Steer now button interrupts the current run and sends your correction as the next turn — falling back to the front of the queue if the agent won't stop.

  • In-app agent (ACP) polish from the July 31 bug bash — eleven quick wins.

    • Code blocks in agent replies render correctly again. A stale Tailwind source path (left over from the package-manager migration) silently dropped every style that ships inside the markdown renderer, leaving a large dead band between a code block's language label and its content, with the copy button floating in the gap. The copy button now sits on the language row and blocks size to their content, capped at a scrollable max height.
    • Syntax highlighting in agent replies. Code output was uniform monochrome; known languages now get theme-aware highlighting in light and dark (via the renderer's shiki plugin, code-split so it stays out of the main bundle).
    • Thinking text is collapsed by default. An agent's reasoning stream now folds to a one-line preview — the latest line while it streams, the first line once settled — with a click to expand. No more walls of internal monologue burying the reply.
    • "Default" now says what it does. Claude's model selector reads "Opus (1M context) · default" instead of "Default (recommended)" — resolved from the agent's own option data, so it tracks whatever the recommendation becomes. Bare defaults with no wire data (Claude's reasoning effort, Codex's collaboration mode) get a short built-in hint, and unknown raw ids render as readable labels ("bypassPermissions" → "Bypass Permissions"). Adapter-supplied names and descriptions always win when present.
    • Agent picker: predictable order and consistent names. Agents you've picked recently sort first (alphabetical after that), and registry display names are normalized at ingest — a manifest that ships an all-lowercase name ("cursor") is title-cased, while branded capitalization (GitHub Copilot, VT Code, goose) passes through untouched.
    • Installing/starting states are visibly alive. The agent mark now breathes alongside the shimmering status line (it was static), and the resume-row spinner no longer risks inheriting an invisible stroke. Both respect reduced-motion.
    • One word for agent chats: "chat". The dock mixed four nouns for the same thing — "Restore sessions", "Delete this conversation?", "New thread with…", "New … chat". Agent surfaces now say chat everywhere: the history button is "Reopen a past chat", the delete confirm "Delete this chat?", the resume fallback "New chat with…". Terminal tabs keep "session" — they aren't chats. The delete icon also no longer sticks open on the history menu's first row.
    • Clearer agent-visibility copy. Settings → Configure agents now names the menus an enabled agent appears in instead of "Turn one off to hide it everywhere."
    • The "Archived" badge is gone. A reopened past conversation no longer shows an ambiguous "Archived" chip — the chat was never read-only, and the composer's "Pick up where you left off" placeholder already says what matters: send a message and the conversation resumes.
  • In-app agent (ACP) threads: three improvements.

    • Tool-call rows say what the agent did, not which tool it called. A row used to show the adapter's raw tool identifier, so an OpenKnowledge write read as mcp__open-knowledge__write and never named the document. OpenKnowledge's own tools now read as plain sentences — "OpenKnowledge wrote to meetings/standup", "OpenKnowledge searched for bordeaux blend", "OpenKnowledge edited articles/malbec" — recognized across the different names each harness puts on the wire (Claude, Codex, and Pi each spell the same tool differently; Cursor sends no tool name at all, so those rows are unchanged). Every other tool keeps the title its agent wrote and now gets an icon matched to what it does: moving, switching mode, and fetching each had a wrong or missing glyph before.
    • Deleting a conversation that is open in a tab is blocked. Reopening an archived conversation from the history menu doesn't unarchive it, so the same conversation could be listed in history and displayed in a tab at once — and deleting it there pulled the transcript out from under the view showing it. Delete is now disabled on those rows, with a tooltip saying to close the tab first. Reopening still works, and conversations with no open tab delete as before.
    • The presence bar no longer blinks on every agent turn. An in-app thread published a presence entry when it became ready, when a turn started, and again when it ended; each expires after five seconds, so a chip flickered in and out around every prompt. Agents connected over OpenKnowledge's tools already publish continuous presence, so those entries were redundant. Presence for a thread now appears only when the agent actually writes a document through the thread, and that entry finally carries the agent's own brand icon instead of a generic one.
  • Open the command palette with Cmd+P / Ctrl+P, in addition to Cmd+K.

    Cmd+K is dual-role — with text selected in the visual editor it adds a link instead of opening the palette — which meant that in exactly that state there was no keyboard route to the palette at all. Cmd+P is unconditional: it opens the palette from anywhere, including mid-selection, so the palette is always one chord away.

    It is also the chord most editors use to find a file, so it should do roughly what you expect if you arrive from one. On the web this now opens the palette rather than the browser's print dialog; printing is still available from the browser's own menu.

  • Gate the F0 shell-snap e2e on a contention-invariant coupling ratio instead of a fixed millisecond budget. The old shellMs < 500 assertion encoded "finishes within 500ms on whatever machine runs it" as a stand-in for "the shell is decoupled from editor mount cost" — those coincide only while runner speed is constant, and the constant had eroded from 1.9x local-healthy to ~0.99x CI-healthy, so it reddened on correct code.

  • Fenced code blocks tagged gherkin (or the feature / cucumber / bdd shorthand) now render with syntax highlighting — Feature, Scenario, Given/When/Then/And/But, Examples, and tags all get their keyword paint, and indentation, data tables, and doc strings pass through as authored. .feature files opened from the sidebar pick up the same grammar.

  • A file you edit now stays open when you click the next one in the sidebar. Single-clicking a file opens it in a preview tab (italic label) that the next click reuses — but editing it left the tab provisional, so a document you had just typed into disappeared as soon as you opened something else. The edit itself was never lost, since it lands in the CRDT the moment you make it, but the tab vanishing read as lost work.

    Editing a document now makes its tab permanent: typing in the visual editor or in source mode, cutting or pasting in source mode, applying a lint fix from the Problems panel or either editor, and editing frontmatter through the property panel — including nested fields, renames, and drag-reordering. Switching a document between source and visual mode promotes it too, as does double-clicking its row in the sidebar, matching double-click on the tab itself. Agent and remote-peer writes deliberately do not: a tab you are only reading stays provisional even while something else writes to the document.

    Preview tabs are otherwise unchanged — clicking a file you never touch still gives up its slot to the next one.

  • The frontmatter schema editor no longer re-presents a typed field as an enum when you give it allowed values. Typing into a string field's allowed-values box added the values correctly but flipped the field's Type select to enum, which read as a silent type change — and switching it back to string then deleted the values you had just entered. Allowed values are a constraint, not a type: a field keeps showing its declared type, and the enum option now shows only for a field the schema leaves untyped (a bare {"enum": [...]}), or while you are explicitly picking it. Picking enum no longer writes a string type in, and moving a field to string keeps its allowed values instead of clearing them. Any other target type still clears them, because it could never satisfy them — a string vocabulary left on a number field makes that field reject every possible value. The same rules apply to an array field's element type.

  • Shutting the server down now waits for in-flight history writes to finish before releasing the history repo. Content-loss checkpoints are written in the background and are never awaited by the editing path, so a burst of them could still be running its git work when shutdown released the repo out from under it. Those writes then landed after the server considered itself stopped, re-creating history state moments after teardown — and anything removing the project directory right after a shutdown could fail partway through. The wait is bounded by the existing shutdown timeout, so a stuck git process still cannot hang exit.

  • The sidebar's file list now fills the space between the toolbar and the project switcher instead of stopping short and leaving a blank strip above the footer. That strip existed to catch the click that clears the creation target — clicking empty space so the next New file lands at the project root rather than inside the folder you have selected. The gesture is unchanged and now works where it always used to: the empty area below the last file, inside the list itself.

  • The skills OK ships now point at each other using the /skill-name form, so a reference from one skill to another is a real link instead of plain text. A pack's orientation skill links to each of its member skills and to the platform /open-knowledge skill, and the member skills link back. Before this, every cross-skill mention was authored as a bare name, which drew no edge in the knowledge graph, got no decoration in the editor, and could not be repointed automatically when a skill was renamed. That is what left prose in the starter packs pointing at names nothing answered to after the July rename. A test derived from the shipped skills on disk now holds the convention, so a new pack or member skill is covered the day it lands.

View v0.49.0 on GitHub