v0.59.2
Point release over v0.59.1: the current stable plus 10 applied commit(s), isolated from the changes still soaking on main.
Applied: ac2e02d, 2cff341, 456497d, a053182, df2a25d, 75062b2, 6b41c29, 9dc4959, 28879c8, 309ebd1
Patch Changes
-
In-app Claude, Codex, and other
npx-distributed agents no longer start under an obsolete Node.js inherited by the desktop app. OpenKnowledge now requires Node.js 22 or newer for these adapters, retries with the compatible runtime from the user's login shell when available, and otherwise offers its private managed Node.js runtime before the agent starts. -
Bug reports and crash logs from the desktop app now record whether assistive technology was active. A recurring family of editor crashes only happens when Chromium is building its accessibility tree, which it does lazily once it detects a screen reader, a voice-input tool, or an input method that reads the screen. Reports carried no trace of that at all, so the single most important fact about these crashes had to be guessed at from circumstance. Two records close the gap. Chromium already stamps the exact accessibility state onto every crash dump it writes, and reports now read it out and put it in the log rather than leaving it buried in a binary file nobody opens. Separately, the app now notes at startup, and again whenever it changes, whether assistive technology is attached, so the timing is visible even on reports that carry no crash dump. Nothing new is collected about you or your documents: the accessibility state is a Chromium setting, identical for everyone running the same assistive tool.
-
Retrying a bug report no longer attaches a different report's screenshot. When you filed one report, it failed to send, and you filed a second one from the same window before retrying the first, the retry's ticket came back carrying the second report's picture. The saved bundle was always right; only the image shown on the ticket was wrong, which is the worst version of it, because the picture is the first thing anyone reads and nothing about it looked stale.
The app used to hold one screenshot per window, captured when the report dialog opened, and looked it up again at the moment a report was sent. Opening the dialog a second time replaced it, so a send that happened after that read whatever the newer dialog had captured. Screenshots are now held per report from the moment the report is written, so a retry attaches the picture that report was composed from no matter what has been filed since. A report with no picture on hand still files without one, which is what already happened for a retry in a later session.
This was only reachable once sends started running in the background with a Try again affordance, so two reports could be in flight from one window at the same time. No released build is affected.
-
When sending a bug report fails, the report you send us afterwards can now explain why. Previously a failed send left a single line reading "network error" and nothing else: not which of the three requests failed, not whether your machine could not find our server or our server refused the connection or a certificate had expired, and no record at all once the logs aged out a week later. A report about a failed report was the one kind of report we could not answer.
Three things changed. Failures across every part of the app now record the error's type and its system error code in the log file that ships inside a report, rather than only on a developer console that nothing captures in an installed app. A failed send now names which request failed, so "our intake was unreachable" and "the storage the file uploads to was unreachable" are told apart. And the small record kept beside each report, which lists every send attempt and how it went, is now included in the reports you send — it is the only account that survives after the logs rotate.
The added detail is deliberately narrow: error types and system error codes, never messages, file paths, or stack traces, since those can carry your folder names and the addresses files upload to. Everything included goes through the same secret scrub as the rest of a report.
-
Fix comments being refused on any passage containing a boundary-whitespace character reference
Selecting text and adding a comment failed with "The quoted passage is not in the document" whenever the selection crossed a space typed just inside bold, italic, or strikethrough, or a space-indented line. The passage matcher treated markdown syntax as elastic but did not know that the display pipeline decodes a narrow set of numeric character references —
 ,	, — which the byte-fidelity serializer mints to hold a phrasing-boundary space across re-parse. Six bytes on disk, one character on screen, and the match broke at the ampersand.Anchoring now decodes those references on whichever side carries them, in both directions, and context scoring makes the same allowance so a highlight no longer degrades near one. References the pipeline does not decode (
&, ,…) still match literally, as they always did. -
Link problems are no longer reported for skill documents: files in a skills folder (
.claude/skills,.agents/skills,.github/skills, and the like) and the skill documents you open from the Skills panel. Skills routinely link to files they create only when they run, so those links were flagged as broken when nothing was wrong. This covers the Problems panel in both scopes and the link diagnostics in source mode. The unresolved-link chips the editor draws as you type, the Links panel, andlinks({ kind: "dead" })still show these targets.The exclusion is scoped to the skills folder, not to the dot directory containing it, so a document like
.github/CI_RUNBOOK.mdkeeps its link findings, as do folder templates under.ok/templates. A skills folder you added yourself at a visible path, such asteam/skills, is ordinary content and is still checked. Links from your other documents into a skill still validate. -
OKF frontmatter problems now appear on the WYSIWYG affordances. The Add-properties badge counts them and stages a pre-named row for a missing required property (
typeincluded), the add-property field picker offers the OKF profile's declared fields with their required hints and descriptions, and the property panel's invalid count includes OKF shape violations, all respecting per-rule toggles and the profile's doc scoping, and working with OKF enabled on its own. On a document with no frontmatter region, an OKF frontmatter violation no longer paints a squiggle on the first body block, and clicking its Problems-panel row no longer scrolls to that block. The property panel owns the error, exactly as it already did for the built-in frontmatter plugin. OKF body rules are untouched: they keep their block decorations and row navigation.The add-property field picker also stops offering fields no widget can author conformantly. This applies to every governing schema, user-authored ones included, not just the OKF profile: a field whose only constraint is
anyOf/oneOf/allOf/not, or an array whose items are objects, is withdrawn, because committing the row the picker suggested would immediately be faulted by the schema that suggested it. A field a schema REQUIRES stays offered whatever its shape, since the missing-property diagnostic stages a row for it either way, and it keeps its schema description. -
Percent-encoded links now resolve to the document they name. A link like
./Agent%20Memory.md(the form the generatedindex.mdemits, and the standard GitHub/Obsidian spelling for names with spaces, parentheses,#,&, or non-ASCII characters) used to resolve to a phantom document containing the raw escapes, so the Problems panel flagged itdead-link, the graph lost the backlink, and clicking it offered to create a new page. The canonical resolvers now decode each path segment per RFC 3986 before path resolution, so lint, graph, navigation, rename rewriting, and asset links all agree with the file on disk. Escapes stay data:%2Fand%5Cnever become a path separator or a..traversal, malformed escapes are kept as literal bytes, and[[wiki]]targets remain verbatim.Renaming or moving a document also re-encodes the links it rewrites. Because the resolvers now decode, a rename matches percent-encoded links for the first time, so the rewriters emit the encoded form rather than a raw name. A document or asset whose name carries a space,
#,?, or a parenthesis keeps a link that still parses after the rename. -
The arrow buttons on a Mermaid diagram now move the view in the direction the arrow points (matching GitHub) and each click eases into place instead of jumping. Respects
prefers-reduced-motion. -
Desktop no longer kills a healthy server that is still starting. The post-spawn wait was a fixed 15 s wall-clock deadline, after which the child was SIGTERM'd even when it was alive and mid-boot — so a project whose boot legitimately took longer than 15 s (large working copies, cold caches, a machine under load) could not be opened at all, and retries reproduced it identically. A child observed alive at the deadline now graduates to a longer bounded wait instead of being killed, and both bounds are overridable via
OK_SPAWN_STARTUP_TIMEOUT_MS/OK_SPAWN_BIND_TIMEOUT_MS.The failure dialog also stops implying that a slow start was caused by whatever the server printed on the way up. Server output is still shown, but it is labelled as the cause only when the child actually exited; a still-running child's output is framed as probably unrelated. Open failures are now written to the desktop log as well as the dialog.
Downloads
| Platform | Architecture | Download |
|---|---|---|
| macOS | Apple Silicon | OpenKnowledge-arm64.dmg |
| Windows | x64 | OpenKnowledge-Setup-x64.exe |
| Windows | arm64 | OpenKnowledge-Setup-arm64.exe |
| Debian / Ubuntu | x64 | OpenKnowledge-amd64.deb |
| Debian / Ubuntu | arm64 | OpenKnowledge-arm64.deb |
| Fedora / RHEL | x64 | OpenKnowledge-x86_64.rpm |
| Fedora / RHEL | arm64 | OpenKnowledge-aarch64.rpm |