OpenKnowledge
Changelog

v0.68.18

Released Sep 5, 2026.

Patch Changes

  • Messages you send in an agent chat now carry their own actions:

    • Send the same prompt to a different agent. Editing a message opens a Send menu that can route it to a brand-new chat, or to a new chat with any other agent you have enabled — a second opinion on a prompt without retyping it. Anything the original carried, such as an attached image, rides along.
    • Copy and edit a sent message. Hovering a sent message shows when it was sent, a button to copy its text, and a button to edit it. The newest message keeps its actions on screen so the send menu is findable.
    • Editing files a new turn rather than rewriting the original. The agent has already answered what you first said, and that reply has to keep making sense, so the original message stays where it is. Edits open in the same field the composer uses, so @-mentions still work.

    Also fixes a bug in that shared field: seeding it with existing text (editing a comment, or opening one of the starter prompts) dropped every line break and swallowed anything written in angle brackets.

  • Opening a document an agent had just written no longer throws you into the middle of it.

    When an agent writes a file, the editor flashes what changed and, if Follow file is on, scrolls that change into view. It picked the scroll target by taking the midpoint of the changed range. For a small edit the midpoint is the edit, so that worked. For a whole-file write, which is what creating or rewriting a file produces, the changed range is the entire document and its midpoint is just the arithmetic middle: a place where nothing in particular happened. Opening such a file within a few seconds of the write, without clicking into the editor first, scrolled you to that arbitrary spot instead of leaving you at the top.

    The follow-scroll now asks whether any part of the change is already on screen, rather than whether the midpoint alone is, and it asks it against the region you can actually read: the editor's scroll container inset by the toolbar at the top and the Ask AI composer at the bottom, rather than the raw window. A change you can already see is not chased, so a whole-file write leaves your position alone, while an agent edit below the fold is still scrolled toward as it was before. How precisely that scroll lands is unchanged, and for an edit far outside the part of the document currently rendered it can still leave you well away from the edit rather than on it.

    Two changes worth naming: a change that is only partly on screen is now left in place rather than recentred, and a change whose only overlap with the window sits behind the toolbar or the composer now counts as hidden rather than visible, so it is followed.

  • The bug reporter can now carry your own images and a contact email.

    • Attach your own screenshots or photos. The report dialog has a "Your images" row that takes up to 3 PNG, JPEG, or WebP images alongside the automatic screenshot — the cases the automatic capture structurally cannot show, like a native system dialog, a second monitor, or a phone photo of a hang. They land inside the diagnostic zip you can inspect before sending, and inline in the ticket next to the automatic screenshot. Images are not redacted, which the row says, and removing one before you create the report is one click. A failed image upload never fails the report.
    • Leave an address, once. A "Share your email for followups" checkbox reveals an email field, the same control the feedback form already has. Unchecked, it never blocks sending. Checked, the address rides the report so the team can reply — which is what reporters have been improvising by typing their name into the note, where it becomes the ticket title.
    • The address is remembered, and forgettable. Once given it prefills next time, on both the bug reporter and the feedback form: one stored value, two surfaces, so the feedback form stops asking you to retype it on every send. Unchecking the box and sending deletes the stored address rather than just switching a flag off — reopen and the field is empty, with nothing recoverable by re-checking it. The value stays on your device and is transmitted only inside a report you sent with the box checked.

    Released desktop builds keep filing exactly as they do today: every wire change is additive, and a client that sends neither field produces a byte-identical ticket.

  • A document that moved on disk while you had it open no longer strands the tab.

    When a git-sync pull (or an external mv) reorganized folders underneath you, the open tab stayed bound to the document's old path. The editor kept rendering the content it already had, but the Outline panel queried a path that no longer existed and showed a red "Page not found." next to a heading count left over from before the move. That error never cleared, because once the old path dropped out of the page list the panel could no longer refetch it.

    Two things changed:

    • The tab follows the document. A move seen by the file watcher now closes the agent sessions and client connections holding that document, as a move made from the sidebar already did. The existing rename-redirect handshake then points each tab at the new path. Moving the document back works too: the tab follows it home and keeps saving, where before the returning path was served a stale copy that silently refused every write. Edits that had not yet reached disk when the move landed are written to the rescue buffer rather than discarded, though reaching them still needs support: they do not yet appear in the Timeline of the document you are rebound to.
    • Panel headers stop disagreeing with their bodies. The Outline, Backlinks, Outgoing, and Local files counts are hidden whenever that section is showing an error, and each of those panels now says plainly that the page is no longer at this path instead of reporting a confident zero. A document that leaves the page list also stops leaving a stale Outline result cached behind it. This covers any failed fetch, not just a move.
  • Source-mode diffs now render through Pierre instead of react-diff-view.

    The Timeline "Source" toggle and the Agent Activity Panel share one diff renderer, and on prose it read poorly: at the narrowest pane width it spent more space on two gutter columns than it left for text, and it broke words mid-token when wrapping. It also had no intra-line highlighting, so a one-word edit inside a long paragraph showed up as two near-identical walls of red and green with nothing marking what actually changed.

    The new renderer gives a single gutter, wraps at word boundaries, and tints the changed words inside the line. Syntax highlighting is deliberately off for prose, where competing colours drown out the diff signal.

    Two defects go with it: the change stepper could show an unreachable denominator such as 4 / 3 because it measured Pierre's rows once and latched, and opening a burst diff for one agent could show another agent's diff on the same document, because the per-document cache key left the agent out.

    Line numbers are now hidden from screen readers on this surface. Pierre renders the gutter and the content as separate columns, so without this a screen reader announced every line number in a block before reaching any of the text.

  • Fixes a bug where a document could drop into a merge-conflict state, replacing the editor with the conflict diff view, even though nothing outside Open Knowledge had touched the file.

    Before writing to a document, the server compares what is on disk against what it believes it last wrote, so that a write from another program is detected but its own recent save is not mistaken for one. That check only remembered a single save per document. When an agent write and your typing kept a document busy enough that two saves were in flight at once, the second save displaced the record of the first, the still-settling first save on disk no longer matched anything the server recognized, and it was treated as a foreign edit. The three-way merge that followed compared the document against its own earlier save and, when both had changed the same paragraph, reported a conflict that never existed. The editor was then swapped for the conflict resolution view and later agent writes were refused with a 409 until the phantom conflict was resolved.

    The server now tracks every save still in flight for a document rather than only the most recent one, the way the file watcher already recognizes its own writes. Those records expire after a minute and are treated as absent by everything that reads them, so a save that never reports completion cannot quietly disable the background durability check for that document. Detection of genuine external edits is unchanged: a write from another program is still reconciled unless it is byte-for-byte a save Open Knowledge is already making.

    Separately, the background check that rescues documents whose edits never reached disk no longer waits forever on a single save. If one document's write stops responding, that document is set aside and reported instead of stalling the check for every other open document until the app is restarted. It is picked up again as soon as that write finishes, whichever way it finishes, so a save that hangs and then fails on a network or cloud-synced folder no longer leaves that document unprotected for the rest of the session.

  • Renaming a file in the sidebar no longer crashes the app when the destination name is already taken.

    If the sidebar's tree already held an entry at the name a file was being renamed into, the rename asked the tree to move an item onto an occupied path, which throws. Because that happened while React was rendering, the surrounding error handling could not catch it and the whole window was replaced with "Something went wrong" instead of the renamed document.

    The move is now skipped when the destination is already in place, matching what the same routine already did for assets, so the rename finishes normally.

  • Terminal content no longer disappears when the terminal changes shape around it.

    Switching to another terminal tab, reordering tabs, or moving the terminal between the bottom dock and the right column could wipe what was on screen. On Windows the symptom was stark: a command you had just run, and its output, would be replaced by a repeated shell prompt, or older scrollback would vanish while the newest lines survived.

    The terminal sizes its grid to fit the box it is drawn in. Hiding a tab, or reparenting the panel mid-move, leaves that box with no size for a moment, and the sizing pass had no way to tell "this box is zero because nothing is drawn right now" from "this box is genuinely tiny". It read a missing size as a real one and fitted the terminal to a grid roughly eleven columns by five rows, then handed that grid to the shell. On Windows the shell owns its screen buffer and repaints it on every resize, so collapsing to a sliver and back destroyed the content in between.

    The terminal now sizes itself only from a box that is actually being drawn, and only the sizing pass that measured that box tells the shell about it. A resize that arrives while the terminal is hidden or mid-move is ignored, and the real size is picked up as soon as it is on screen again, so tab switches, reorders, and moves leave the buffer and the running shell untouched.

    The same rule covers the terminals that come back when you reload the window. They are restored all at once, but only the tab you are looking at has a size yet, so the ones still waiting their turn are no longer told a size that was never measured. Each is told its real size when it is shown.

  • Opening the terminal on a cold start no longer risks an empty dock that never fills in.

    The dock waits for your saved terminal tabs to be read back before it shows anything, and that read had no time limit. If it stalled, the dock opened and then stayed empty forever: no terminal, no message, and no way out short of reloading the window. A dock that was open when you last quit could stay empty even after the read finished, because nothing started a terminal once the restore was given up on.

    The read is now bounded. If it does not come back in time, comes back empty, or errors outright, the dock starts a fresh terminal instead of waiting, so you get a working shell rather than an empty panel. One case is different: if the check for shells that survived the restart fails, a dock being restored stays empty rather than opening a second shell on top of one that may still be running. Any shells that were still running are left running rather than being closed, and the timeout and any shells left behind are written to the log.

    The tradeoff worth knowing: whenever the restore does not complete, whether it timed out, the saved state could not be read, the surviving-shell check failed, or the restore errored, that window stops saving tab changes entirely, so your previous tabs survive to the next launch untouched. Opening, closing, renaming and reordering tabs still work for the rest of that window, they just are not remembered. That is deliberate, because a window that never learned what you had saved should not overwrite it with less. A line is written to the log the first time a save is skipped.

    The "Starting terminal…" spinner also explains itself now. If startup runs long, it adds a line saying so and offers a Reload button, while continuing to wait, so a slow start still finishes on its own.

View v0.68.18 on GitHub