v0.20.0
Released Jun 29, 2026. Part of the OpenKnowledge changelog.
Minor Changes
- Write-time broken-link validation in the Open Knowledge MCP.
write/editnow returnbrokenLinksin the same response — outbound links that don't resolve are surfaced at write time, report-only so the write still lands and you can author a doc before its link target exists. Validation covers every local link, not just docs: the./-onto-a-content-root-path doubling footgun and missing[[wiki]]/ markdown doc targets (no-such-doc), root-escaping paths from one../too many (unresolvable), and links to assets or source files ([src](../../foo.py)) that don't exist on disk at the resolved path (no-such-file). That last reason closes the gap a real codebase-wiki run hit: wrong-depth source-file links that 404 silently because the doc-only link graph never tracked them. The platform and pack skills are updated to point agents atbrokenLinksas the primary write-time check and to clarify that a same-pass forward-reference reports asno-such-docuntil its target lands (thelinks({ kind: "dead" })audit is the authoritative end-state check).
Patch Changes
Shorten the "Codebase wiki" starter-pack description to a single short clause ("Architecture, modules, and flows.") so its card matches the length of the other packs on the starter-pack picker instead of overflowing with a full paragraph.
Rename the
ok install-skillCLI command to a deliberately hidden, unadvertisedok cowork. The old name implied an automatic install it never performed — it builds theopenknowledge.skillbundle and opens the Claude Desktop App for a manual upload (the only path to the separate Skills list Claude Chat & Cowork read, whichok init's editor wiring can't reach). The command is now registered hidden (absent fromok --help), andok initno longer pushes a hint toward it — it is a power-user escape hatch discovered pull-only via the Open Knowledge skill. The underlying bundle build and thePOST /api/install-skillroute are unchanged.Make "Open in agent" (handoff to Claude, Codex, and Cursor) work on Windows and Linux, not just macOS. Install detection was already cross-platform, so on Windows/Linux a registered agent showed an enabled row that, when clicked, failed with a 500 error and a "Couldn't reach …" toast. Handoff dispatch now opens the agent's protocol URL through the OS's registered handler on every platform (
/usr/bin/openon macOS,rundll32on Windows,xdg-openon Linux), and Cursor's workspace launch already worked cross-platform. On Windows/Linux the server first confirms the agent's URL scheme is actually registered, so an uninstalled agent reports "not installed" instead of a misleading success.Desktop: enable the openknowledge.ai update proxy for the beta channel. Beta builds now fetch updates through
openknowledge.ai/updates/beta, which 302s to the byte-identical GitHub asset (preserving the manifest sha512 and the macOS signature) so updates can be counted per version. Stable still reads the GitHubpublish:config; it gets the same path once an end-to-end beta update is confirmed. A feed failure reverts to the GitHub provider for the session, so auto-update reliability never drops below GitHub-direct.Desktop: add an opt-in path to fetch updates through the openknowledge.ai proxy so updates can be counted per version. When the build's channel is enabled, electron-updater's feed is pointed at
openknowledge.ai/updates/{channel}and requests are tagged withx-ok-from-version/x-ok-channelheaders. Default-off — production keeps reading the GitHubpublish:config until the proxy is verified live, then the enabled-channel set flips to beta-first. A feed failure on the first check reverts to the GitHub provider for the session, so auto-update reliability never drops below GitHub-direct.Stop starter-pack and other card descriptions from overflowing their cards. The "Codebase wiki" starter pack and the slash-command MirrorSource / Mirror block previews had descriptions long enough to wrap to many lines and stretch their cards; those are now concise. The description text on the starter-pack picker, the slash-command block preview, the Navigator project-launcher cards, and the share-receive dialog is now line-clamped, so any long description truncates cleanly instead of distorting the layout.
Fix
ok starthanging for about 10 seconds on Ctrl+C when a live client was connected. If a browser preview tab or an agent/MCP session held a WebSocket open, shutdown left that socket alive, so the WebSocket-server close and the HTTP-server close each blocked until a 5-second internal timeout fired — adding ~10s of delay and printing an alarmingAggregateErroron a routine quit. Shutdown now drains the live upgrade sockets up front (mirroring the existing drain inok ui), so both close steps finish promptly and the server lock is released right away.Fix a starter-pack skill being unable to reinstall after a user uninstalls it. Pack skills are named
open-knowledge-pack-<packId>, which sits under theopen-knowledge*prefix reserved for OK's shipped skills. The seed installs them by copying directly, but a user-triggered reinstall re-runs the install validation, which rejected the reserved prefix and failed with "uses the reservedopen-knowledge*prefix." The install guard now exempts theopen-knowledge-pack-*namespace (OK's own shipped pack content), so reinstalling a pack skill works while user-authoredopen-knowledge*names stay blocked.Fix skill reference graph links, the skills-dock flicker, and re-seed data safety.
- A
[[references/<name>]]wiki-link inside a skill's SKILL.md now resolves to that skill's bundle reference doc and forms a real backlink and graph edge. Previously the natural wiki form silently mis-resolved to a phantom top-level doc (only an absolute[[.ok/skills/<name>/references/<name>]]or a markdown link resolved), so a skill's references never appeared as links or backlinks. Adds a sharedresolveSkillBundleWikiTargethelper used by the link index, and updates the write-skill guidance to author references as wiki-links (a backtick code path renders dead and never joins the graph). - The skills sidebar no longer flickers (list flashing empty then repopulating) on every skill create/edit/install/move. The list now revalidates in place instead of resetting to a loading state.
- Re-running seed no longer overwrites a user-edited starter-pack skill.
installPackSkillonly authors the source when it does not already exist; an existing skill keeps its edits and shadow history while still refreshing its editor projection and install marker. POST /api/create-pagenow rejects a path inside.ok/(or a managed-artifact doc name), so a page can no longer be created inside the indexed.ok/skills/**namespace and bypass skill-schema validation.- The
installMCP tool description now lists OpenCode (.opencode/skills/) as a valid projection target, matching the schema.
- A
Fix skill move/scope-change losing bundle files and dropping references from the link graph. A cross-scope skill move (global ↔ project) copied only
SKILL.mdand then deleted the source, silently losing everyreferences/**andscripts/**file; both the MCPmoveverb and the editor's scope switch now copy the full bundle through the per-type write path (project.mdreferences rejoin the backlink/tag graph; global references and all scripts are written fs-direct) before deleting the source, aborting without data loss on any partial-copy failure. A same-scope skill rename now re-indexes the relocatedSKILL.mdand its.mdreferences into the live backlink/tag graph (previously they sat unindexed until a manual rescan). The editor also reconciles open skill tabs after a server-side move — a tab whose skill moved scopes retargets to the new location, and one whose skill was deleted closes — so no stale phantom tab is left behind. Also adds the new skill write routes to the mutating-route CSRF guard and the conflict gate.Fix Open Knowledge Desktop offering to set up a project inside a subfolder of a linked git worktree. Picking a subdirectory (for example
public/open-knowledge) inside agit worktree addcheckout misclassified it as a worktree root and showed "Setup Open Knowledge in this folder" in place, scaffolding.ok/in the subfolder instead of promoting to the git root. Subfolders of a linked worktree now correctly fall through to git-root promotion; only the worktree root itself is treated as a standalone project.Run the git preflight at the project-setup boundary so a broken or PATH-invisible git surfaces recoverable install/upgrade guidance instead of a raw error.
Creating a project, opening a folder, cloning from GitHub, and
ok initnow verify git is usable before invoking it, and run against the exact git the preflight validated (the resolved path for in-process git, or an enriched PATH for the spawned clone). When git is missing or unusable they report platform-specific install guidance;ok initexits 78 (EX_CONFIG) on a git-preflight failure, matchingok start.These setup paths now require git 2.31 or newer — the same floor
ok startand the desktop app already enforce at launch.Show global skill references in the link graph, connected to their skill.
A global skill's
SKILL.mdand itsreferences/*.mdnow appear as connected nodes in the link graph, the same as a project skill — even though global skills live in~/.ok/skills/outside the project content tree. Global bundle docs are ingested as graph nodes (at boot, on branch switch, and live via the managed-artifact watcher) and connected by structural edges derived from the bundle path. The connection is within-bundle only: a global skill is never linked into a specific project's knowledge base (a global reference's wiki-links are not followed), and its cluster is visible from every project since global skills are shared across all of them. Clicking a global reference node in the graph opens it read-only through the scope-aware skill-file viewer.Stop showing the "this project is running an older version of OpenKnowledge … restart it to use the current version" notification after a routine app update. When the desktop app updated, the background server it had started kept running on the old version (it's designed to survive the app quitting), so the freshly-updated app reconnected to that stale server and flagged the version mismatch on nearly every update. The app now shuts that server down as part of the update install itself, so the relaunched app starts a fresh matching server and there's nothing to warn about. Shutdown is gated to the update-install moment only — a normal app quit still leaves your server running, as before — and the server flushes any in-flight edits before exiting, so no work is lost.
Desktop: stop showing the sticky "Installed CLI shims." startup toast when an app upgrade only repoints the internal
~/.ok/binsymlinks. The startup PATH-reclaim toast now fires only for changes the user can see or act on — a shell rc-file edit, an opt-out, a legacy-symlink cleanup, or a failure. A no-op symlink repoint (the common case on every upgrade or bundle-path change) is now silent; the repoint still happens and still emits the structuredpath-install-symlink-successevent for operators. Restores the spec's "silent if no meaningful user-facing change" contract.Make a project skill's references show up connected in the graph, and let global skill bundle files be opened.
- A project skill's
SKILL.mdand itsreferences/*.mdnow appear connected in the link graph automatically, whether the body references them as[[wiki-links]]or as plain backticked paths. The references were already graph nodes; this adds the structural edges between a skill'sSKILL.mdand its own reference docs, derived strictly from the bundle path (.ok/skills/<name>/). Regular documents and folders are unaffected — co-membership in an ordinary folder does not create edges. Authored wiki-links keep working and are not double-drawn. - Clicking a global skill's reference or script in the Skills sidebar now opens it (read-only) instead of failing with "could not be found." Global skill bundle files live in
~/.ok/skills/outside the project content tree, so they are now read through the scope-aware skill-file endpoint rather than as a project content-dir asset. A fetch failure shows a terminal state instead of a perpetual loading spinner. - The write-skill guidance is updated: project skill references auto-connect in the graph regardless of how they are referenced, a wiki-link is only needed for a clickable inline link, and global skill references should stay plain backtick paths since global references are not graph docs.
- A project skill's
Make skills URL-addressable in the editor and resolvable by the MCP, so a skill behaves like a document. The skill editor now has its own route (
#/__skill__/<scope>/<name>): opening a skill updates the URL, so it is reload-stable, shareable, and deep-linkable; loading a skill URL opens straight into the editor with the file sidebar visible. Closing routes the URL back to the document underneath, and navigating to a document dismisses the skill editor. ThewriteandeditMCP tools now ride a route-onlypreviewUrlfor skills (the same preview envelope documents already carry), and thepreview_urltool accepts a{ skill }target, so an agent that authors a skill in Open Knowledge can hand back a URL that opens it in the running editor.Creating a skill now opens the editor directly instead of a modal: the "New skill" action drops a draft into the main editor pane with an inline Project/Personal scope toggle in its Properties panel. Filling in a name and description enables Create; once it commits, the editor re-points to the saved skill and switches into the same autosave edit experience, so authoring a new skill and editing an existing one are one continuous surface.
Render a global skill's
.md/.mdxreferences as formatted read-only markdown instead of raw source.Opening a global skill bundle file in the Skills sidebar previously showed the raw markdown source. Markdown references now render formatted (headings, bold, lists) read-only — the same rendering the editor uses (via the shared extension set, with no editing and no collaboration binding). Scripts and other non-markdown files keep the source view.
Render skill reference graph nodes as resolved, and address review follow-ups.
- A skill-bundle reference node in the link graph now renders as a normal resolved node instead of the dashed-red "missing" treatment. The node always resolved to a real, openable read-only viewer (clicking it works), but it was misclassified as a missing link target, so it read as broken.
- A failed skill move no longer turns into a 500 when the post-rename graph re-index throws — the rename already succeeded, so a re-index failure is logged and swallowed.
- The skills-list handler now logs when
readdirSyncfails instead of silently returning an empty list, and the bundle-file path classifier rejects NUL bytes for parity with its sibling validators. - The starter-pack update dialog and toasts show the skill's display name instead of its raw internal id, and the skill menu's update action reads as an imperative ("Update skill").
Clarify the skills import prompt. The one-time banner now states what Import actually does: it moves the editor-dir skills into
.ok/skillsand replaces the.claude,.codex, etc. copies with symlinks back to it, so the knowledge base is the single place to edit them and every editor stays in sync. It also flags the consequences a user needs before clicking: if those folders are committed to git the change should be reviewed, and symlinks can behave differently on some editors and on Windows.Stop two ways agents get derailed around the skill surface.
The
skillsMCP tool now short-circuits OpenKnowledge's own built-in skills instead of 404-ing. An agent told to "load the open-knowledge skill" would callskills({ name: "open-knowledge" }), hit a bareSkill not found., and fall back to cat-ing the bundled SKILL.md. The built-ins (open-knowledge,open-knowledge-discovery,open-knowledge-write-skill) are runtime agent skills projected into editor host dirs, never KB content skills, so a READ aimed at one now returns a teaching error explaining it is already in the agent's loaded skill list and is not fetched through this tool. User-authoredopen-knowledge-pack-*skills are unaffected, and the tool description states the boundary up front.The project SKILL.md escape hatch now tells agents that their initial tool list is not exhaustive: some clients (notably Codex) defer MCP tools behind a lazy
tool_searchstep, somcp__open-knowledge__*is absent until discovered. Absence from the visible list means "not discovered yet," not "not registered" — agents must run tool discovery before invoking the native-tools escape hatch.
Keep an open browser tab's
ok startserver alive. The web editor now holds a single, app-lifetime/collab/keepaliveWebSocket — the same presence-invisible keepalive the desktop app and MCP shim already use — so the server's 30-minute idle-shutdown can no longer fire out from under an open tab when no document is focused or during a brief reconnect. Previously, with no doc open the only liveness signal was the per-document collab connections, so an idle tab could lose its server and every editor/tool call would fail until reload. Closing the tab still lets the server idle-shut-down normally, and the keepalive reconnects across a server restart on a new port. Multiple tabs each hold their own keepalive. The keepalive adds no presence-bar entry.Fix Git auto-sync when server-spawned Git needs the user's home directory, SSH agent, or credential-helper environment to reach a remote. This most visibly affected Windows repositories using SSH remotes, where
ok syncand editor sync could fail with "Could not read from remote repository" while the samegit fetchorgit pushworked in a terminal.Because preserving the home directory also lets server-spawned Git read the user's global config, OK now pins
commit.gpgsign=falseandcore.autocrlf=falsefor its own Git commands only (via-c, leaving the user's own Git untouched): the first prevents the unattended sync commit from aborting when a global signing config can't prompt for a passphrase, and the second keeps line-ending conversion from churning content against OK's byte-exact round-trip.