v0.32.0-beta.0
Pre-releaseDelta since previous beta (v0.31.0-beta.8) — 1 new changeset.
Minor Changes
-
Add content rules (a markdown linter with native markdownlint support) and themes as a toggleable plugin, introducing the new Settings → Plugins area. Shipping the two together makes the Plugins taxonomy legible from day one: content rules are a project-scope plugin (shared via git) and Themes is a user-scope plugin (personal to this device) — the two kinds of plugin the system is built around.
Content rules. Powered by markdownlint (the engine behind VS Code's markdownlint), the linter surfaces common issues — hard tabs, trailing whitespace, heading-increment skips, inconsistent list markers, and more — as non-blocking warnings, with a gutter marker, hover tooltip, and a one-click "Fix" for auto-fixable rules. WYSIWYG mode flags the offending block with the same wavy underline — or, for textless blocks like thematic breaks and images, an outline so the mark is always visible. Enable it per project in Settings → This project → Plugins.
Your rules live in your project's own
.markdownlint.{json,jsonc,yaml,yml}(or.markdownlintrc) file — the portable, ecosystem-standard config, discovered at the content root — not in Open Knowledge's config. With no file present, the default matches the VS Code markdownlint extension exactly: every rule on, exceptMD013(line-length). The only OK-config surface is the plugin toggle (contentRules.markdownlint.enabled, project scope).Problems panel. A new Problems tab in the right-hand document panel lists every problem for the active document with a count badge, and clicking a row jumps to the offending spot: the exact line and column in source mode, the containing block in WYSIWYG. It reads the document's source CRDT directly, so problems show in WYSIWYG mode too — not just source mode; the WYSIWYG block markers lint those same source bytes, so byte-level findings (hard tabs, trailing spaces, blank-line runs) paint in both modes. A "This doc / Project" scope toggle runs a whole-project audit on demand (a refresh button re-runs it; nothing polls in the background), listing every violating file with its diagnostics and error/warning totals. Clicking a diagnostic opens the offending file and lands on the violation — the exact line in source mode, the containing block in WYSIWYG. Auto-fixable diagnostics carry a one-click Fix in every mode: the CodeMirror lint action in source mode, a Fix button on the panel row, and a Fix button in the WYSIWYG block's hover tooltip — each applies the fix straight to the document's source.
Settings → Plugins. A new Plugins management page (under This project) groups plugins by scope — "This project — shared via git" (content rules) and "This device — personal" (Themes) — and each enabled plugin appears under a Plugins header in the settings sidebar with its own panel. Whole-project audits run from the Problems panel, not Settings.
Full-catalog rule browser. The markdownlint panel lists every rule the installed engine ships (53 today), grouped by category, with search over id/alias/name and an "Only modified" filter. Rule metadata — names, descriptions, documentation links, option types — is generated from markdownlint's own config schema, so the catalog always matches the installed engine version. Toggle any rule on or off and the change lands in your native
.markdownlint.json(created from OK's tuned defaults on first edit). Expanding a rule row reveals its documentation link and a typed field per option: switches for booleans, dropdowns for enums, number inputs honoring the schema's minimum/maximum, plain text for strings, and tag-pill lists for arrays — setMD013'sline_length,MD003's heading style, orMD043's required headings without hand-editing JSON. The rare option shape with no generic control shows an "Edit in config file" chip.Themes as a plugin. The IDE color palettes (Dracula, Catppuccin Frappé, Catppuccin Latte, Monokai, Gruvbox, Solarized, and a six-seed-color Custom theme with live preview) now live under Settings → Plugins → Themes, and the Themes plugin itself can be toggled off — disabling it reverts the whole app to the default palette (including the pre-paint flash cache) without losing your saved choice. Palettes are personal, user-scoped preferences (
appearance.colorTheme,appearance.customTheme,appearance.colorThemeEnabled) applied flash-free on launch; dark IDE palettes force dark mode so Tailwinddark:styles stay correct, and switching back to Default restores your saved light/dark choice.Native config, the markdownlint-cli2 way. Rules live in the project's own
.markdownlint.{jsonc,json,yaml,yml}files and are honored exactly as markdownlint-cli2 would: full JSONC (comments, trailing commas, BOM),extendschains (relative file paths, escape-guarded; package refs declined with a clear diagnostic;extends: nullaccepted), and a per-directory cascade — the nearest config file on a document's path governs it wholesale, with no OK-flavored merging underneath. The VS Code-parity defaults apply only when a project has no markdownlint file at all, and the first rule edit from Settings materializes them into a real.markdownlint.json. Executable configs (.cjs/.mjs) are detected but never executed. Malformed configs and unresolvableextendssurface loudly (Settings,ok lint, and the lint API) instead of silently falling back, with the underlying parse/read detail in the message.Edits are faithful to your file. Alias-keyed configs (
line-lengthforMD013, case-insensitive, last matching key wins) are resolved with markdownlint's own semantics, and rule edits rewrite the key form already in your file instead of appending a duplicate canonical id. Toggling a rule in a.markdownlint.jsoncpreserves your comments, and unrelated keys and formatting stay untouched. Severity strings ("error"/"warning") — valid in markdownlint's own schema — load and lint normally; the rule browser shows such a rule as enabled with a read-only severity chip, and discloses before an edit that saving replaces the severity string. Lint reads are symlink-safe: a path that resolves outside the content directory is refused, matching the escape protection on every other read surface.Headless + MCP. A new
ok lint [path]CLI command lints the project (or a folder/file) from the terminal, with--fixto apply auto-fixable rules and--jsonfor structured output — exits non-zero on problems, CI-friendly. A newlintMCP tool surfaces problems to connected agents — for a single document or as a whole-project audit, capped at 10 files × 10 diagnostics with explicit "… and N more" indicators and always-accurate totals. Passingfix: truewith a document applies markdownlint's auto-fixes in place through the collaborative document — attributed to the agent and reflected in the live preview, exactly like the editor's Fix button, never an unattributed shell edit; it stays auto-approvable because the fix is a recoverable, shadow-versioned content write likewrite/edit. Agentwrite/editresponses also carry the written document's problems as advisory warnings, so agents see the same issues the editor shows without an extra round-trip. The lint HTTP API is grouped under/api/lint/*.