p.enthalabs

GitHub - inkeep/open-knowledge: Beautiful, AI-native markdown editor and LLM Wiki

Skip to content

Navigation Menu

Toggle navigation

[](https://github.com/)

Sign in

Appearance settings

* Platform

* AI CODE CREATION

- GitHub Copilot Write better code with AI

- GitHub Copilot app Direct agents from issue to merge

- MCP Registry New Integrate external tools

* DEVELOPER WORKFLOWS

- Actions Automate any workflow

- Codespaces Instant dev environments

- Issues Plan and track work

- Code Review Manage code changes

* APPLICATION SECURITY

- GitHub Advanced Security Find and fix vulnerabilities

- Code security Secure your code as you build

- Secret protection Stop leaks before they start

* EXPLORE

- Why GitHub

- Documentation

- Blog

- Changelog

- Marketplace

View all features

* Solutions

* BY COMPANY SIZE

- Enterprises

- Small and medium teams

- Startups

- Nonprofits

* BY USE CASE

- App Modernization

- DevSecOps

- DevOps

- CI/CD

- View all use cases

* BY INDUSTRY

- Healthcare

- Financial services

- Manufacturing

- Government

- View all industries

View all solutions

* Resources

* EXPLORE BY TOPIC

- AI

- Software Development

- DevOps

- Security

- View all topics

* EXPLORE BY TYPE

- Customer stories

- Events & webinars

- Ebooks & reports

- Business insights

- GitHub Skills

* SUPPORT & SERVICES

- Documentation

- Customer support

- Community forum

- Trust center

- Partners

View all resources

* Open Source

* COMMUNITY

- GitHub Sponsors Fund open source developers

* PROGRAMS

- Security Lab

- Maintainer Community

- Accelerator

- GitHub Stars

- Archive Program

* REPOSITORIES

- Topics

- Trending

- Collections

* Enterprise

* ENTERPRISE SOLUTIONS

- Enterprise platform AI-powered developer platform

* AVAILABLE ADD-ONS

- GitHub Advanced Security Enterprise-grade security features

- Copilot for Business Enterprise-grade AI features

- Premium Support Enterprise-grade 24/7 support

- Pricing

Search or jump to...

Search code, repositories, users, issues, pull requests...

Search

Clear

Search syntax tips

Provide feedback

We read every piece of feedback, and take your input very seriously.

- [x] Include my email address so I can be contacted

Cancel Submit feedback

Saved searches

Use saved searches to filter your results more quickly

Name

Query

To see all available qualifiers, see our documentation.

Cancel Create saved search

Sign in

Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert

{{ message }}

Uh oh!

There was an error while loading. Please reload this page.

inkeep/**open-knowledge**Public

- NotificationsYou must be signed in to change notification settings

- Fork 78

- Star 1.6k

- Code

- Issues 10

- Pull requests 4

- Actions

- Projects

- Security and quality 0

- Insights

Additional navigation options

- Code

- Issues

- Pull requests

- Actions

- Projects

- Security and quality

- Insights

[](https://github.com/inkeep/open-knowledge)

inkeep/open-knowledge

main

**3**Branches**213**Tags

[](https://github.com/inkeep/open-knowledge/branches)[](https://github.com/inkeep/open-knowledge/tags)

Go to file

Code

Open more actions menu

Folders and files

| Name | Name | Last commit message | Last commit date | | --- | --- | --- | --- |

| ## Latest commit [![Image 3: inkeep-oss-sync[bot]](https://avatars.githubusercontent.com/u/123133689?v=4&size=40)](https://github.com/apps/inkeep-oss-sync)[inkeep-oss-sync[bot]](https://github.com/inkeep/open-knowledge/commits?author=inkeep-oss-sync%5Bbot%5D) Fix image and file paste/drop in the packaged desktop app, which… Open commit details success Jun 30, 2026 64f7da0·Jun 30, 2026 ## History 784 Commits Open commit details [](https://github.com/inkeep/open-knowledge/commits/main/)784 Commits |

| [.changeset](https://github.com/inkeep/open-knowledge/tree/main/.changeset ".changeset") | [.changeset](https://github.com/inkeep/open-knowledge/tree/main/.changeset ".changeset") | [Fix (open knowledge) image paste in the packaged desktop app (#2288)](https://github.com/inkeep/open-knowledge/commit/4750499faf1b75d134f29f69f08cac2c413167c2 "Fix (open knowledge) image paste in the packaged desktop app (#2288) * Fix image and file paste/drop in the packaged desktop app * fixes GitOrigin-RevId: 89b42f78fa8a528a96a36742578178c693f1750a") | Jun 30, 2026 |

| [.github](https://github.com/inkeep/open-knowledge/tree/main/.github ".github") | [.github](https://github.com/inkeep/open-knowledge/tree/main/.github ".github") | [Fix harness MCP-config write safety (data-loss on launch) (#2192)](https://github.com/inkeep/open-knowledge/commit/a54b65ee3df8eee15298cdc273f25a7af2086816 "Fix harness MCP-config write safety (data-loss on launch) (#2192) * docs(open-knowledge): spec for harness MCP-config write safety Plan to fix the codex-config-trash data-loss bug across all five coding harnesses (Claude Code, Claude Desktop, Cursor, OpenCode, Codex). OK's weak parsers (smol-toml, JSON.parse) throw on valid configs, and the every-launch repair sweep then resets the file; lossy round-trips also strip comments and retype values. The spec covers a napi-rs Rust addon porting Codex's toml_edit config editor (insert-only, format-preserving) for Codex TOML, a surgical jsonc-parser editor for the four JSON harnesses, a non-destructive classify/repair path, symlink write-through, and BOM/EOL fidelity. Grounded by reproductions plus eleven evidence files. Implementation lands in follow-up commits on this branch. * chore(md-conformance): refresh ng-anchors catalog file counts Pre-existing baseline drift, independent of any feature work. The committed ng-anchors-catalog.json recorded productionFileCount 83 and testFileCount 179, but the deterministic enumeration over packages/core/src/markdown, packages/core/src/extensions, and the test globs now counts 84 and 180. A source/test file was added without regenerating the catalog, leaving the freshness gate in bun run check red on the baseline. Regenerated via enumerate-ng-anchors; only the count metadata changed, no anchors or slugs. * [US-001] non-destructive MCP-config classification: split corrupt into absent + decline classifyExistingMcpEntry no longer collapses blank and unparseable configs into one 'corrupt' kind. Blank/whitespace/0-byte files now classify as 'absent' (safe to create into); a present non-empty config OK cannot parse or read classifies as 'decline' carrying a bounded reason enum (McpDeclineReason), never the raw parser message. A half-written file read mid-write by a concurrent harness classifies as decline, not creatable-blank. The McpEntryClassification union keeps four kinds (absent, no-entry, present, decline). The three classification consumers (claude-readiness, mcp-wiring, project-mcp-reclaim) move to the decline kind; their reclaim disposition is unchanged here and becomes non-destructive in the next story. Tests: blank/whitespace to absent, invalid JSON/TOML to decline with a bounded reason, truncated JSON/TOML to decline, and a declined config is left byte-unchanged by classify. * [US-002] non-destructive desktop MCP reclaim: delete .broken rename Both desktop reclaim sweeps now leave a present, unparseable harness config byte-untouched and skip registering, emitting a bounded mcp-config-decline signal {scope, surface, editorId, reason} instead of renaming it to .broken-<ts> and writing a fresh near-empty config. mcp-wiring.ts startup sweep drops the rename + fresh-write branch and the corruptBackupFailures/now/fs state. project-mcp-reclaim.ts drops moveCorruptAside, the backup DI, and the reclaimed-from-corrupt status. Both push a decline disposition and emit the signal. The bounded decline-event builder is wired and exported from index.ts (McpConfigDeclineInput kept module-local). A reset-repro regression (real fs + real classifyExistingMcpEntry on an i64 TOML config) asserts the file stays byte-unchanged with no .broken sidecar and no write dispatched. The project-reclaim decline tests are updated to the non-destructive behavior and an AC3 create-into-blank test is added. repair-mcp-configs.ts was already non-destructive and is unchanged. * [US-003] capable JSONC parse on the read/classify path Swap the JSON read/classify path from JSON.parse to jsonc-parser so valid harness configs are no longer false-flagged unparseable and reset: - readJsonConfig and classifyExistingMcpEntry now parse via a tolerant JSONC scanner (line and block comments, trailing commas) and forgive the lone InvalidSymbol a leading UTF-8 BOM produces, so a comment-rich or BOM-prefixed config classifies by its real content. - classify surfaces a duplicate top-level container key as a decline (duplicate-container) instead of silently editing whichever block the value parse happens to keep. The check is keyed to each harness's real container key, so a repeated unrelated sibling key stays no-entry. - The JSON branch parses the bytes classify already read (no second read) and shares classifyContainer with the TOML branch; TOML keeps its current parser. - Add jsonc-parser to tsdown alwaysBundle so the bundled CLI resolves it inside the packaged app. Add classify unit tests for JSONC comments, trailing commas, leading BOM, duplicate container (cursor and opencode), and the unrelated-sibling-key case. * [US-004] surgical comment-preserving JSON/JSONC MCP write editor Replace the whole-file JSON.stringify spread-merge in the write spine with a jsonc-parser modify/applyEdits upsert that touches only OK's own entry, so a registration write preserves the user's comments, formatting, key order, and a leading BOM in their harness config instead of reflowing the whole document. - upsertJsonMcpConfig: absent/blank create fresh; present+parseable upsert in place; oversize (>10 MiB), duplicate container key, and unparseable all decline and leave the file byte-unchanged. Idempotent: an already-current entry short-circuits to a byte-identical no-op. - New 'declined' EditorMcpResult action carrying a bounded decline reason, so a guest-ownership leave-untouched is neither a write nor a failure. Threaded through formatInitResult, the desktop wiring mirror + logging, and the CLI repair outcome. - Pre-write backup of the original bytes on a present, parseable write; size gate runs before the parse+modify so a multi-MB file costs only a read. - Resolve jsonc-parser to its ESM entry in tsdown so its submodule loads inline in the bundle. Its UMD main left bare require('./impl/*') calls that crashed the desktop-loaded dist; a bundled-load integration test guards the fix. TOML keeps the whole-file path for now; the format-preserving native write lands separately. * [US-005] napi-rs native-config crate + capable TOML classify + load-probe fallback Add packages/native-config, a Rust/napi addon wrapping toml_edit, and wire its capable parse into the harness-config classify path so a valid Codex config carrying a 64-bit integer or a microsecond datetime is no longer mis-flagged unparseable (the enabler of the reported config reset). A synchronous load-probe factory returns the native engine when the .node loads and a JS smol-toml fallback otherwise; on the fallback the write spine declines a present non-trivial TOML config rather than risk a lossy whole-file rewrite, and only creates into an absent or blank file. Crate: pure N-API-free parse/JSON-projection module (accepts i64 past 2^53 and microsecond datetimes, errors on genuinely-malformed input) with 6 cargo tests, a thin napi 3 wrapper, and a turbo test task that runs cargo test so the gate covers it. Engine: src/native/toml-config-engine.ts probes and falls back the way createTokenStore does, with a loader parameter for deterministic tests. The classify TOML branch now reads through the engine using the bytes already read. Updated the reset-repro regression: under the capable parser the i64 config classifies as no-entry, so the no-create sweep leaves it untouched rather than declining, and it is still byte-unchanged with no .broken sidecar. Packaging: cli workspace dependency, tsdown neverBundle, biome and knip ignores for the generated loader, notices regen. The packaged-desktop extraResources copy and the cross-platform prebuild matrix are tracked as their own work; the packaged fallback stays a non-destructive decline until then. * [US-006] insert-only single-key toml_edit upsert/remove engine in native-config * [US-007] port Codex edit-test conformance floor + symlink resolution + Codex attribution * [US-008] wire Codex TOML write through the native addon + BOM/EOL/trailing-newline wrapper Route writeEditorMcpConfig's TOML branch through upsertTomlMcpConfig: the native toml_edit insert-only upsert touches only OK's own entry, and a thin wrapper captures and re-applies the source file's leading BOM, dominant EOL, and trailing-newline state (toml_edit strips the BOM, normalizes CRLF to LF, and always emits a trailing newline). A present, parseable config gets a pre-write backup before the atomic write; an unchanged config is a byte-identical no-op. On the JS fallback a present non-blank config declines rather than a lossy whole-file rewrite. The engine becomes a discriminated union on backend so only the native arm carries upsertEntry; the fallback can only parse. OK's own string values now serialize as single-line escaped basic strings (matching the prior smol-toml writer) so every newline in the document is structural, which makes the blanket CRLF re-apply provably safe and keeps OK's resolver chain LF-internal on any line-ending convention. The native upsert reports whether OK's entry already existed so the spine labels register-vs-update without re-parsing. * [US-009] symlink write-through on the harness write path Resolve a (possibly symlinked) harness config to its real write target so a dotfile-managed (stow/chezmoi) config is written through to its target instead of being replaced by a regular file and orphaning the dotfiles-repo copy. New cli/src/native/symlink-resolve.ts: resolveHarnessWritePaths prefers the native conformance-tested resolver and degrades to a pure-JS mirror of Codex's resolve_symlink_write_paths. Symlink traversal has no capability gap, so the JS mirror keeps write-through working for all five harnesses and on platforms with no prebuilt binary. writeEditorMcpConfig resolves inside the file lock and writes to the resolved target; a cyclic chain collapses to a regular file, breaking the link. Atomicity and the cross-process lock are unchanged; core stays native-free. Tests run one contract suite against both the JS and native resolvers, and a real-spine write-through regression asserts the symlink survives and the real target received the entry (JSON and TOML), plus cycle-break. * [US-010] package native-config addon into the desktop bundle The Codex TOML harness write goes through the native-config toml_edit addon from two runtime consumers in a packaged build: the bundled CLI subprocess and the desktop main process (the MCP repair sweep calls writeUserMcpConfigs in-process). Mirror the @napi-rs/keyring packaging so both can resolve it. - Declare @inkeep/open-knowledge-native-config as a desktop dependency so electron-builder includes it in app.asar for the in-process main consumer. - extraResources copies the addon onto the bundled CLI's own resolution path (cli/node_modules), filtered to the napi loader, types, manifest, and the platform .node so the Rust target/ tree never ships. Unlike keyring this is one workspace package whose binary sits beside its loader. - asarUnpack the addon package dir so the loader and the .node it requires stay co-located on the real filesystem. - Extend the forcing-function packaging test: the addon now ships, so it leaves KNOWN_UNCOVERED; add guards that the extraResources rule ships both loader and binary, that asarUnpack covers it, and that the build artifacts exist after a build. When the binary cannot ship or load the TOML write degrades to a non-destructive decline, never a lossy write. This is the packaging sub-piece of US-010. The cross-platform prebuild matrix (release CI) and the packaged-DMG smoke remain, both gated. * [US-011] consolidated cross-harness FR1 acceptance matrix + surgical-text counterfactual guard * [US-010] fix knip dependency tracing for the native addon Remove the now-stale cli ignoreDependencies entry for @inkeep/open-knowledge-native-config (knip traces it via the native binding test requires), and add a desktop ignoreDependencies entry (the desktop main reaches the engine through the bundled CLI's require factory at runtime, so there is no static specifier for knip to follow, but the dependency is declared for the electron-builder extraResources copy). * [US-010] bundle native-config prebuilt binaries into the CLI + prebuild CI Ship the toml_edit addon to all platforms via Option 3 (bundle the prebuilt binaries into the CLI tarball; native-config stays private, no per-platform optional-dependency packages): - prebuild CI: a standalone 8-target napi-rs matrix workflow builds one .node per target (darwin arm64/x64, linux gnu/musl arm64/x64, windows msvc arm64/x64) and a combine job asserts all 8 are present - CLI build copies the napi loader + every present .node into dist/native/ (shipped via files:[dist]); a CommonJS package.json beside the loader keeps Node from mis-parsing it as ESM under the CLI's type:module tree - a shared resolver tries the bundled dist/native loader first, then the workspace package, then the existing non-destructive fallback - THIRD_PARTY_NOTICES gains a maintained, Cargo.lock-checked attribution section for the addon's statically linked Rust crates - AC5 committable smoke: a verifier that loads the bundled addon from the packaged layout and round-trips it, a driver test, and a runbook (the live in-Electron-process step is deferred to a signed-DMG QA run) * [US-010] wire native-config prebuilt binaries into the npm release Add a resilient release.yml step that stages the latest successful native-config-prebuild bundle into packages/native-config/ before the CLI build, so the published npm CLI carries all eight platform binaries rather than only the release runner's host target. Warn-not-fail: a missing bundle ships host-only and non-host platforms use the non-destructive smol-toml fallback, so it can never make a release worse than the host-only status quo. Binaries are ABI-stable; the latest run's set is reused until native-config changes. Also strip two branch-introduced process markers from source comments (comment-discipline): the decision reference in the Rust conformance test and the story reference in the smoke driver header. * fixup! local-review: baseline (pre-review state) * fixup! local-review: baseline (pre-review state) * fixup! local-review: address findings (pass 1) * fix(open-knowledge): native-config to devDependencies (npm install fix) The published CLI listed the private, never-published @inkeep/open-knowledge-native-config in runtime dependencies. At publish, workspace:* rewrites to the on-disk 0.0.0, so npm install @inkeep/open-knowledge would try to resolve that from the registry, 404, and abort for every user. Move it to devDependencies alongside the bundled siblings -app/-core/-server; the addon still ships in dist/native/ and loads dist-relative, and only tests bare-require it. Validated in reports/bundled-native-addon-dep-placement. Also append post-ship corrigendum breadcrumbs to SPEC D14/AC5 and the scope/failure-mode/non-goal references: the additive-path pre-write backup was removed entirely. It was write-only (nothing reads .ok-backup, so no recovery) and a secret-disclosure footprint; EC5 concurrent-truncation is covered by D13/AC7 truncation-to-decline plus the atomic tmp+rename. * feat(open-knowledge): pin fallback non-destruction + stable-release binary gate Four changes hardening MCP-config write safety and the native-config release path: - mcp-wiring.test.ts: add a sibling regression test in the reset-repro block that forces the JS smol-toml fallback engine (the path every off-macOS / no-prebuilt-binary user runs) and proves the boot sweep leaves a valid i64 Codex config byte-identical: no fresh write, no .broken-* sidecar, only a bounded mcp-config-decline signal. Drives the real classify through the cli surface; imports classify from cli source so the engine override binds to the same instance the classify reads. - release.yml: hard-fail a stable @latest cut when fewer than 8 native-config binaries stage or the prebuild run is missing, while beta keeps the resilient warn-and-proceed path. A stable publish silently shipping host-only native binaries is a fidelity regression. The staged count is written to the job summary either way. - release.yml: verify the staged prebuild run's head commit is an ancestor of the release commit before trusting its binaries, so the native code shipped on every CLI invocation was built from source actually in the release. A non-ancestor degrades like the missing-binaries case (warn for beta, hard-fail for stable). - native-config/src/lib.rs: note that remove_mcp_server is exposed for the future ok uninstall flow so it is not re-flagged as dead surface; it stays as the symmetric counterpart to upsert_mcp_server. * chore(open-knowledge): regenerate md-audit byte-audit after rebase onto main * ci(open-knowledge): use bun-install-ci.sh in native-config prebuild (bunfig cooldown) * ci(open-knowledge): gate native-config cargo conformance tests in OK validation native-config's 40 toml_edit conformance tests (test = cargo test) ran in no required CI job. The per-package test loop in the open-knowledge / test matrix cell never listed it, and native-config-prebuild.yml only builds the addon, so the fidelity core of the MCP-config write-safety work was unguarded. check:ok-ci-test-coverage flagged the gap. Gate it rather than allowlist it away: add the package to the per-package loop with a 360s budget sized for a cold cargo compile, and add a test-gated dtolnay/rust-toolchain step plus a cargo cache so the test cell has a toolchain (the pre-build napi build and cargo test both need cargo). The action SHA and toolchain match release.yml and native-config-prebuild.yml. * fix(open-knowledge): gate classify path on config size + review hardening Close the classify-path oversize asymmetry. classifyExistingMcpEntry now stat-gates a config past JSON_CONFIG_MAX_BYTES before reading, mirroring the write path's oversize decline, so a history-bloated ~/.claude.json (tens of MB) is left untouched without a full read and JSONC parse on every launch. It returns the existing decline/oversize classification, so no caller changes are needed (no caller branches on the reason value, and the decline telemetry event already accepts oversize). statSync avoids pulling the file into memory just to measure it. A RED test pins that the gate fires ahead of the parse: a valid JSON payload that would otherwise classify no-entry now declines oversize and is left byte-unchanged. Also addresses the code review findings on this PR: - cargo cache key now includes hashFiles(Cargo.lock, Cargo.toml) plus restore-keys in native-config-prebuild.yml and the OK validation workflow, so a dependency bump no longer reuses a stale crate cache - init.ts native upsert and config-read catches emit debugNativeLoadFailure so a present-but-broken native addon is diagnosable under OK_DEBUG_NATIVE instead of collapsing silently to unparseable - mcp-decline-event surface is narrowed from open string to a bounded union so the decline event stays bounded-cardinality at the type level - symlink-resolve native catch and the readlinkSync catch emit debug traces * fix(open-knowledge): honest fallback decline reason + CRLF JSON write test Two re-review findings, both in this PR's own code: - The TOML write path's JS-fallback branch declined a present config with reason 'unparseable', but it never parses the config: the real cause is that the format-preserving native engine is unavailable and a fallback rewrite would be lossy. Add a distinct 'no-native-writer' McpDeclineReason and emit it there, so decline telemetry is no longer misattributed to a parse failure. - Add CRLF coverage to the JSON surgical-write path (the TOML path already had it). A uniformly-CRLF config keeps its line endings byte-for-byte and the inserted entry is written as CRLF too, with no bare LF leaking in. * docs(open-knowledge): ok:macos-vm CLI-on-VM validation reference + golden gotchas Add an ok:macos-vm reference (references/cli-on-vm-validation.md) for the build-free CLI validation path: npm pack + rsyncToVM + npm i -g, where the prebuilt arm64 native-config .node matches the golden so the napi config writer loads with no build-ok-desktop and no Rust toolchain. Document the consumer-side delta (ok init writes the open-knowledge MCP entry; the general consumer-fidelity method lives in eng:qa, loaded via /qa). Record golden substrate gotchas in macos-vm + bake-lume-golden failure modes (stale npm _cacache, no Rust, no timeout binary, ok init needs git), and note inject.sh does not cover the Claude Code CLI. * docs(open-knowledge): fix stale classify comment + CRLF JSDoc * chore(open-knowledge): add Rust toolchain to lume golden 2026-06-28 (#2244) * chore(open-knowledge): add Rust toolchain to lume golden 2026-06-28 Bake a Rust toolchain into the lume macOS golden so build-ok-desktop builds the native-config napi addon in-VM, retiring the per-fork rustup install and the build-free-only workaround. - layer 13d: rustup + cargo + the aarch64-apple-darwin target, shimmed into /usr/local/bin so non-login ssh finds it - layer 13e: sudo-purge the inherited root-owned ~/.npm/_cacache (the EEXIST/EACCES that broke a fork's npm i -g) and chown ~/.npm to lume - verify.sh: check 13 asserts cargo + rustc + the aarch64 target - promote DEFAULT_GOLDEN to ok-tahoe-base-substrate-only-2026-06-28 (fork-extend off 06-06); update lineage in the 3 allowlisted docs - retire the now-false \"No Rust toolchain\" notes - macos-vm skill: add an Observability section (headless vs VNC, the password rationale, the shutdown-hang caveat) Validated on a fresh fork: verify.sh 16/0 (Aqua healthy, Rust present) plus a cargo build of toml_edit, native-config's core dep, in 3.98s. * docs(open-knowledge): propagate Rust + 13e to secondary doc references * fix(open-knowledge): exclude declined writes from startup-repair status * test(open-knowledge): add Codex MCP tool-call QA scenario (cx-s1) Adds a lume-QA scenario proving Codex.app invokes a real OpenKnowledge MCP tool, asserted by the load-bearing mcp-tool-trace rung. It is the Codex analogue of cd-s1-claude and the first scenario showing an agent, not a bare Node client, fire a tools/call to OK. - cx-s1-codex.ts: seeds a project, wires ~/.codex/config.toml through the MCP-trace proxy (published bunx server, approval_policy=never so the tool call is not gated behind an approval card), drives Codex over CDP, and asserts a tools/call frame in the trace. - lume-qa-cx-s1-codex.e2e.ts: host wrapper (fork golden, inject auth, install trace proxy, run, evaluate rungs). - codex-cdp-evals.ts: shared Codex CDP-driving primitives (wizard dismiss, fill and submit, chat scrape) plus a new tool-approval handler. - ok-e2e-codex.ts: migrated to import the shared evals, removing the duplicated inline copies. Manual-only (OK_LUME_QA=1 bun run lume-qa cx-s1-codex); not in CI. Validated on the 2026-06-28 golden: 3 of 3 pass with approval_policy=never (Codex gpt-5.4 agent calling the OK config tool). --------- GitOrigin-RevId: afa186ece2dfb2e8384973e7db52e64e3088ec35") | Jun 30, 2026 |

| [assets](https://github.com/inkeep/open-knowledge/tree/main/assets "assets") | [assets](https://github.com/inkeep/open-knowledge/tree/main/assets "assets") | [docs(readme): add OpenKnowledge wordmark masthead (#2214)](https://github.com/inkeep/open-knowledge/commit/83f89e76ef7ca6dff4f2b072085d7d530cad1360 "docs(readme): add OpenKnowledge wordmark masthead (#2214) * docs(readme): add OpenKnowledge wordmark masthead + content updates Add a centered light/dark wordmark masthead (replacing the text H1), with two theme variants in assets/ and the drop-shadow filter removed so the icon stays crisp as vector. Also fold in the Website nav link, Usage and Support sections, and an X follow-up footer. * docs(readme): transparent hero corners + content/layout edits Replace the hero with a transparent-backdrop version at the same animation and fidelity (2736x1540 lossless, one cycle, ~592K) so its rounded corners no longer show white wedges in dark mode. Plus README edits: clickable logo, left-aligned masthead/nav, tightened copy, Usage starter-pack note. Fix typos (WYSIWYG, Obsidian, br). GitOrigin-RevId: 6ee7f46d91476c988177333636e665cf7a98b29b") | Jun 27, 2026 |

| [biome-plugins](https://github.com/inkeep/open-knowledge/tree/main/biome-plugins "biome-plugins") | [biome-plugins](https://github.com/inkeep/open-knowledge/tree/main/biome-plugins "biome-plugins") | [Mirror-exclude Open Knowledge engine-test apparatus from public mirro…](https://github.com/inkeep/open-knowledge/commit/71c2e82bec8b56f238aaddffb41ebed4f7465a9e "Mirror-exclude Open Knowledge engine-test apparatus from public mirror (#2069) * [US-001] mirror-exclude engine-test apparatus from public OK mirror Add three exclude globs (app/tests/fidelity, core/src/markdown *.test.ts, core/src/bridge *.test.ts) plus the four byte-fidelity-oracle tests (prd-6654-multi-client-repro, source-mode-byte-preservation, init-load-byte-stable and its stress e2e sibling) to the public-open-knowledge Copybara manifest, so OK's never-shipped correctness-measurement apparatus stays off the public mirror. Drop the two single-file excludes now subsumed by the globs (invariant-i8, parser-drop-closure); init-load-byte-stable-corpus-coverage stays excluded. A top-level manifest note records that the excluded set equals the future packages/engine private test set so a later source-split inherits the boundary. Engine source and runtime behavior are byte-unchanged in the materialized export (only test-file deletions, zero content diffs); this is a mirror-coverage change only. Regenerate the Copybara config. * [US-002] strip mirror-orphaned engine-test runners from public OK manifest After US-001 mirror-excluded the engine-test apparatus, several mirrored runners still named the now-absent test paths. Add 7 headDriftCheck strips to copybara/manifests/public-open-knowledge.json so the public mirror carries no dangling test references: - app package.json: drop test:fidelity script + init-load-byte-stable.e2e.ts from the test:e2e Playwright list - core package.json: drop test:perf:fallback, test:perf:r15-guard, gen:guard-flanking-matrix scripts (they run excluded markdown tests) - turbo.json: drop the orphaned test:fidelity, test:perf:fallback, test:perf:r15-guard tasks (inputs named excluded paths; no mirrored runner invokes them) - root package.json: drop test:fidelity from the check:full:parallel turbo args (check was already stripped by the existing full-value rule) conversion-fidelity is intentionally not stripped: it is not an excluded path (the real test ships public; the turbo input pointing at tests/integration/ is a pre-existing stale ref to a non-existent file). Verified: materialized export has 0 excluded-path refs in mirrored package.json/turbo.json; mirror-includes + manifest-head-drift green; diff vs pre-change baseline shows only the 4 config files differ with zero engine-source delta and zero additions (NG1 held). * [US-003] add mirror-test-policy guard: engine-test default-private, moat import-guard, dangling-ref New scripts/check-mirror-test-policy.{mjs,test.mjs}, wired into check:structural with a check:mirror-test-policy alias. Three checks against the public-open-knowledge manifest: - engine-domain *.test.ts shipping public outside the exclude globs (default-private), - a public-shipping test importing the moat (any mirror-excluded path, the byte-stable snapshot fixtures, or the tolerance-class catalog symbols), - a mirrored runner (package.json script / turbo input) naming an excluded engine-test path. Import detection parses multi-line, comment-stripped imports, so it spans the common multi-line import block and ignores a moat symbol mentioned only in a doc comment (the reason an import-name check is sound where a per-line text grep is not). The guard surfaced a byte-oracle leak the enumeration missed: single-file-ephemeral.e2e.ts imports the byte-stable snapshot fixture and asserts on-disk byte identity (a sibling of init-load-byte-stable.e2e.ts). Excluded it from the mirror and stripped its app test:e2e reference so the public clone stays clean. The Monorepo Structural Validation gate enforces the guard via test:scripts, which runs check-mirror-test-policy.test.mjs (non-vacuity per check plus a real-tree-green assertion), matching the check-manifest-head-drift enforcement pattern. Engine source byte-unchanged. * [US-004] add GritQL round-trip-identity oracle ban for public OK tests Forbid the byte-fidelity round-trip oracle in public-mirrored tests: a GritQL plugin flags serialize(parse(x)) (and the MarkdownManager method form) asserted equal to the same x via toBe/toEqual/toStrictEqual or ===. Metavariable reuse enforces input equals expected, so fixed-literal contract tests and the normalizeBridge Bridge-invariant contract (precedent #38) stay green, and the !== normalizing-construct detector is unaffected. Scoped to the public test surface, excluding the engine-test clusters that legitimately own the oracle (fidelity, markdown/bridge precision, md-conformance), mirroring the copybara exclude set. Fixture pairs 10 positives with 7 negatives; the lint-plugins fixture-test pins toBe(10) for non-vacuity and precision and asserts override-only registration. * [US-005] add public render-HTML contract test + wire it into the OK gate Add packages/core/tests/contract/render-html.test.ts: a public contract test for the @inkeep/open-knowledge-core render surface (markdownToHtml / mdastToHtml). It pins the documented-construct rendering (headings, strong/ emphasis/code, lists, link, blockquote, fenced code) and the outbound URL-scheme sanitization at the OK to external-destination boundary: javascript:/data:/vbscript:/file: are dropped from href/src while https, mailto, tel, and relative/anchor URLs survive. Every expectation is a fixed HTML literal (never the input compared to itself) and the only imports are the public barrel and bun:test, so the test carries no round-trip oracle or correctness-measurement apparatus. The file lives in core/tests/contract/ (outside the src/markdown strip glob) so it ships on the public mirror. core's test script ran only src/, so the base check gate would never have discovered it; broaden it to \"bun test src/ tests/contract/\" and add tests/contract to the turbo test task inputs so the contract tier runs in CI and mirrors public. No engine source, LICENSE, or dist change. * [US-005] fix render-html test import to relative barrel The core 'test' script runs 'bun test src/ tests/contract/' without --conditions development, so the package-name self-import (@inkeep/open-knowledge-core) cannot resolve to src/index.ts. Switch to the relative barrel import '../../src/index.ts' — same public surface, matching the existing core/tests/{health,perf} convention. * [review] address pre-QA review findings Major: - head-drift test: bump asserted strip count 10 to 18 to match the 8 new engine-test-apparatus runner strips added with the mirror-exclusion. The test runs in test:scripts (a required per-PR gate + pre-push) and was red; the OK bun gate never runs root scripts/*.test.mjs, so it slipped. - knip: the tests/fidelity/** mirror-exclude orphans 4 app devDeps (fast-check, commonmark.json, remark-mdx, remark-parse) on a public clone, breaking R2/G5 (knip clean on a public checkout). Ignore them only when the fidelity suite is absent, so the private tree stays hint-free and the public clone's knip gate stays green. - render-html contract: the URL-sanitization test pinned a denylist-of-4 while safe-url.ts is a fail-closed allowlist and the comprehensive suites are mirror-excluded. Add allowlist-closure (blob/intent/view-source rejected), entity-obfuscation, the full allowlist (ftp/sms/http), and reword the docstring to allowlist framing. Minor: - mirror-test-policy guard Check A: filter on isTestFile so an engine-domain *.e2e.ts under markdown/bridge (whose globs are *.test.ts-only) cannot slip past the default-private backstop; add a non-vacuity test. - drop the internal copybara/manifests path from 3 public-shipping files; it does not exist on the public mirror. Hardening: - remove dead glob clause c2 in isEngineTestExcludeGlob (subsumed by c3). - wire check:mirror-test-policy into the Monorepo Structural Validation gate per SPEC 5b/11; it was reachable per-PR only via the test's real-tree assertion. * re-sync test:fidelity turbo strip after integrating origin/main main added two inputs to turbo.json's test:fidelity task (tests/fixtures/** and ../md-conformance/src/**/*.ts). The byte-exact manifest strip that drops that orphaned task from the public mirror no longer matched, so the head-drift gate correctly flagged a potential leak. Update the strip's before to the current source and regenerate the generated copybara config. * address review feedback: guard non-vacuity + fixture completeness + docs From the claude[bot] approve-with-suggestions review: - add a Check B non-vacuity test for BRIDGE_TOLERANCE_CLASSES and a Check C non-vacuity test for the turbo.json task-input path (both matched the per-check convention but lacked a synthetic red case). - assert the full biome override negative-glob set in the GritQL fixture test (was 3 cluster globs; now all 10, incl the enumerated byte-oracle tests). - guard against a bunx spawn failure masking as 0 diagnostics in that test. - document the best-effort limits of stripComments (nested template literals) and parseImports (alias capture) in the mirror-test-policy guard. - add a tests/contract/README per the tests/health and tests/perf convention. Declined listing check:mirror-test-policy in root AGENTS.md: that file is at the 38500-byte test:scripts cap, and the guard is already documented in its script header and the check:structural wiring. * address re-review: manifest .e2e.ts globs + guard full-path + turbo-output tests From the claude[bot] re-review (approve / ship-it, 3 low-risk considers): - exclude *.e2e.ts companions for the markdown/bridge engine clusters in the manifest, so the manifest is self-defending: the policy guard already backstops engine-domain .e2e.ts, but the manifest now proactively covers the full engine-test set rather than relying solely on the guard. - add a Check B non-vacuity test planting a literal full-path exclude (the enumerated byte-oracle entries), not only the fidelity dir glob. - add a Check C non-vacuity test for the turbo OUTPUTS branch (inputs was already pinned). --------- GitOrigin-RevId: ba42b39524e0fe4df3141f7c329a7e799cf35563") | Jun 25, 2026 |

| [docs](https://github.com/inkeep/open-knowledge/tree/main/docs "docs") | [docs](https://github.com/inkeep/open-knowledge/tree/main/docs "docs") | [main reset: post-stable v0.21.0 (#2290)](https://github.com/inkeep/open-knowledge/commit/329fa0ae7ca51002f5aa6fe2cf9fb785d3d36100 "main reset: post-stable v0.21.0 (#2290) GitOrigin-RevId: 1efa31c899c6fbee01fe80e3828efeb1f8eac28b") | Jun 30, 2026 |

| [packages](https://github.com/inkeep/open-knowledge/tree/main/packages "packages") | [packages](https://github.com/inkeep/open-knowledge/tree/main/packages "packages") | [Fix (open knowledge) image paste in the packaged desktop app (#2288)](https://github.com/inkeep/open-knowledge/commit/4750499faf1b75d134f29f69f08cac2c413167c2 "Fix (open knowledge) image paste in the packaged desktop app (#2288) * Fix image and file paste/drop in the packaged desktop app * fixes GitOrigin-RevId: 89b42f78fa8a528a96a36742578178c693f1750a") | Jun 30, 2026 |

| [patches](https://github.com/inkeep/open-knowledge/tree/main/patches "patches") | [patches](https://github.com/inkeep/open-knowledge/tree/main/patches "patches") | [feat(open-knowledge): VS Code-style file-tree sidebar density (#1903)](https://github.com/inkeep/open-knowledge/commit/ff4ddfaee5cff039ffc3fc72744c1f6149b7f4e4 "feat(open-knowledge): VS Code-style file-tree sidebar density (#1903) * US-001: tighten file-tree per-level indent and row height Apply Pierre's `density: 'compact'` preset (factor 0.8, itemHeight 24) plus explicit `--trees-level-gap-override: 3px` and `--trees-item-row-gap-override: 2px` so the sidebar's per-level horizontal step lands near VS Code's flat ~10px (down from ~20px at Pierre defaults). Row height drops to 24px via the preset. Extracted createFileTreeStyle and FILE_TREE_DENSITY_OPTIONS into a new file-tree-density.ts so bun unit tests can import the config without pulling in @lingui/core/macro through FileTree.tsx. The new test pins the density preset and the three CSS-var overrides; per-level pixel measurement remains the job of a Playwright e2e since jsdom does not compute calc() through Pierre's shadow root. * US-002: show file-tree indent guides at rest Pierre's spacing-item border has opacity 0 at rest and only lifts to 0.75 under :host(:hover), so the tight per-level indent leaves rows without a visible parent-trace. Republish the rule in @layer unsafe with a 0.5 resting opacity (hover 0.85), and lift Pierre's default guide-bg alpha from 25% to 30% so the rendered border still reads against the sidebar in both themes after the per-element opacity multiplies it down. The new FILE_TREE_INDENT_GUIDE_CSS lives in file-tree-density.ts beside the density tuning it depends on, so a single test file pins both. Three new bun unit tests cover: the new bg-override exists in both themes within the 25-35% alpha window, the CSS targets Pierre's spacing-item selector, and the hover state stays stronger than rest. * US-003: shrink file-tree icon-width to 14px * [US-004] style sticky folder header with elevation tint and hairline divider * [US-005] enable compact folders (flattenEmptyDirectories) for the sidebar tree * docs(open-knowledge): sidebar density VS Code tricks spec * local-review fixups: e2e race, color-mix space, forced-colors, comments - e2e: wait for the seeded breadcrumb in the shadow tree (not just shadow root presence) — shadow-root mount precedes async row render and the evaluate could see an empty DOM under CI load. - color-mix in oklab everywhere (matches the rest of packages/app/src/); affects the indent-guide-bg override and the sticky-header bg tint. - sticky header: add `@media (forced-colors: active)` fallback so the hairline divider remains visible in Windows High Contrast (parallel to FILE_TREE_ROOT_DROP_CSS). - file-tree-density.ts: comment why `--trees-item-height: 24px` lives on the React style prop even though Pierre would set the same value from JS (CSS-only consumers + pre-empts JS write). - FileTree.tsx: drop the stale \"createFileTreeStyle below\" pointer; it lives in file-tree-density.ts now. * sticky-header comment: cover both gates (conditional render + visibility:hidden) Original comment only mentioned Pierre's CSS `visibility: hidden` rule, which omits the conditional-render path. Pierre uses both: the overlay element is rendered only when stickyRows is non-empty, and when populated but the user is at scrollTop=0 the CSS rule hides it. A maintainer debugging \"why does my CSS not apply at rest\" needs both paths to find the right answer. * fixup! local-review: address findings (pass 1) * fixup! local-review: address findings (pass 2) * chore(open-knowledge): bump @pierre/trees to 1.0.0-beta.4; reveal via scrollToPath beta.4 narrowed the useFileTree model surface (dropped getFocusedIndex/ getItemHeight). Migrate reveal-on-activate to Pierre's native scrollToPath (offset: nearest, focus: false), removing the hand-rolled scroll math in file-tree-scroll.ts that reimplemented it. * feat(open-knowledge): end-truncate folder names in the file tree Folders rendered middle-truncation (open-...wledge) because Pierre center- splits dot-less names, while files end-truncate as a side effect of the badge hiding their extension segment. Extend the badge observer to recompose folder rows the same way: write the full name into the first truncate segment and hide the second, so folders end-truncate (open-knowl...) consistently with files. * chore(open-knowledge): regenerate THIRD_PARTY_NOTICES for pierre/trees beta.4 * chore(open-knowledge): raise app main-bundle size budget to 410 kB The sidebar-density feature (file-tree-density module, folder end-truncation logic, extension-badge additions) adds ~1.3 kB gzipped to the main index bundle, pushing it from under to 408.26 kB. Raise the size-limit budget from 407 kB to 410 kB to cover the legitimate increase with a small headroom margin. * fix(open-knowledge): defer compact folders and re-port pierre patch to beta.4 The @pierre/trees beta.4 bump surfaced two regressions: 1. beta.4 flipped the flattenEmptyDirectories default from false to true, so omitting it silently enabled compact folders. Compact folders does not flatten single-child chains under the show-all-files + lazy-per-dir-fetch default (children aren't loaded until expand, so Pierre can't collapse the chain), so pin it off explicitly and defer the feature to a follow-up. Remove the two compact-folders e2e; the density test now asserts it is off. 2. The root-drop patch (PRD-7043: drop a nested item on empty tree space to promote it to root) was keyed to beta.3, so Bun stopped applying it after the bump, breaking the feature. Re-port the two FileTreeView hunks to a beta.4 patch (dropping the obsolete getFocusedIndex hunk now that reveal uses scrollToPath); remove the stale beta.3 patch and regenerate notices. * refactor(open-knowledge): dedup file-tree extension-badge segment helpers Address review feedback: extract resolveBasenameSegment(row) shared by the extension-badge path and the folder end-truncation recompose (both target Pierre's leading middle-truncate segment), and route setSegmentText and trimTrailingDotInBasenameSegment through one mapSegmentTextNodes core so the visible/overflow text-node walk lives in a single place. Behavior unchanged. GitOrigin-RevId: 04f70f64e2b4e1e5cc8727b432dccdcdf924b1db") | Jun 17, 2026 |

| [scripts](https://github.com/inkeep/open-knowledge/tree/main/scripts "scripts") | [scripts](https://github.com/inkeep/open-knowledge/tree/main/scripts "scripts") | [Fix harness MCP-config write safety (data-loss on launch) (#2192)](https://github.com/inkeep/open-knowledge/commit/a54b65ee3df8eee15298cdc273f25a7af2086816 "Fix harness MCP-config write safety (data-loss on launch) (#2192) * docs(open-knowledge): spec for harness MCP-config write safety Plan to fix the codex-config-trash data-loss bug across all five coding harnesses (Claude Code, Claude Desktop, Cursor, OpenCode, Codex). OK's weak parsers (smol-toml, JSON.parse) throw on valid configs, and the every-launch repair sweep then resets the file; lossy round-trips also strip comments and retype values. The spec covers a napi-rs Rust addon porting Codex's toml_edit config editor (insert-only, format-preserving) for Codex TOML, a surgical jsonc-parser editor for the four JSON harnesses, a non-destructive classify/repair path, symlink write-through, and BOM/EOL fidelity. Grounded by reproductions plus eleven evidence files. Implementation lands in follow-up commits on this branch. * chore(md-conformance): refresh ng-anchors catalog file counts Pre-existing baseline drift, independent of any feature work. The committed ng-anchors-catalog.json recorded productionFileCount 83 and testFileCount 179, but the deterministic enumeration over packages/core/src/markdown, packages/core/src/extensions, and the test globs now counts 84 and 180. A source/test file was added without regenerating the catalog, leaving the freshness gate in bun run check red on the baseline. Regenerated via enumerate-ng-anchors; only the count metadata changed, no anchors or slugs. * [US-001] non-destructive MCP-config classification: split corrupt into absent + decline classifyExistingMcpEntry no longer collapses blank and unparseable configs into one 'corrupt' kind. Blank/whitespace/0-byte files now classify as 'absent' (safe to create into); a present non-empty config OK cannot parse or read classifies as 'decline' carrying a bounded reason enum (McpDeclineReason), never the raw parser message. A half-written file read mid-write by a concurrent harness classifies as decline, not creatable-blank. The McpEntryClassification union keeps four kinds (absent, no-entry, present, decline). The three classification consumers (claude-readiness, mcp-wiring, project-mcp-reclaim) move to the decline kind; their reclaim disposition is unchanged here and becomes non-destructive in the next story. Tests: blank/whitespace to absent, invalid JSON/TOML to decline with a bounded reason, truncated JSON/TOML to decline, and a declined config is left byte-unchanged by classify. * [US-002] non-destructive desktop MCP reclaim: delete .broken rename Both desktop reclaim sweeps now leave a present, unparseable harness c