✨ Highlights

This release focuses on consolidating offline link generation, securing dependency installs, and optimised test execution. Key issues addressed include #179 (offline folder navigation redirects), #167/#175 (SEO metadata omissions in offline builds), and security hardening against command injection (CWE-78) in the installer.

Furthermore, we have resolved performance bottlenecks in the test runner, dropping test suite latency from 15 minutes to under 2 minutes.

No breaking changes. No new config required. Existing configurations, plugins, and CI pipelines work unchanged.

🐛 Fix: Unified Offline Navigation (#179)

Previously, system-generated navigation elements (logo, breadcrumbs, version/language switchers, sidebar) emitted directory-style links (such as ./ or /). When viewed offline over file://, browsers resolved these to filesystem directory paths rather than explicit HTML files, resulting in directory listings or broken pages.

The fix: all URL generation has been consolidated into a single source of truth (packages/parser/src/utils/url-utils.ts). Navigational components now route through bound helpers (buildRelativeUrl and buildAbsoluteUrl). In --offline mode, all generated URLs automatically resolve directory endpoints to explicit index.html targets (e.g. ./index.html or ../index.html), ensuring bulletproof navigation across local filesystems.

🧹 SEO & Metadata Robustness (#167, #175, #177)

Canonical links, Open Graph tags (og:url, og:image), and Twitter Card tags require absolute URLs. When siteUrl was missing or the project was compiled in --offline mode, these tags resolved to broken root-relative paths like /guide/, which caused metadata errors.

The fix: the SEO plugin now checks siteUrl and offline flags. Canonical and Og/Twitter metadata tags are omitted in offline builds or if siteUrl is not configured, unless they are explicitly absolute URLs.

🔒 Security: Command Spawning Hardened (CWE-78)

Peer-dependency installation within @docmd/plugin-search has been refactored to prevent command injection risks.

The fix: we replaced shell-based execution (execSync) with a secure, centralised runtime-dependency installer. Package managers are now spawned directly via argument arrays without shell expansion, ensuring robust cross-platform execution in CI and production environments.

⚡ Optimisation: Test-Suite Dependency Resolving

The feature integration and asset pipeline tests previously triggered costly, network-heavy package installations (e.g. downloading docmd-search and its peer dependencies) in temporary test folders, driving execution time up to 15 minutes.

The fix: we introduced the DOCMD_TEST_SEARCH_PATH environment variable. During test runs, the plugin bypasses external npm package downloads and resolves search and template dependencies directly from the monorepo workspace. The entire test suite now completes in under two minutes.

🚀 Optimisation: Incremental Semantic Indexing Cache Reuse

Previously, the search plugin compiled the search index from scratch on every rebuild/reload, taking 30–42 seconds because the output directory (site/.docmd-search/) was cleared.

The fix:

  • The search plugin now writes the semantic index to the docs source directory (docs/.docmd-search/ or version directory ver.dir/.docmd-search/) which is preserved across builds and checked into version control.
  • It runs incremental indexing in this folder (reusing existing manifests and batch files) and recursively copies the final generated index assets to the site output directory.
  • This results in a 100x+ build speedup (warm rebuilds complete in under 300ms).

⚙️ Rust Engine Native Addon DX & Routing

  • Local Binary Copying: Configured postinstall.cjs in @docmd/engine-rust to check for sibling rust-binaries/bin/ folders, enabling the Rust engine to be used during development and testing of new versions prior to npm CDNs publication.
  • Task Routing: Updated task routing to only dispatch native-supported tasks (file:* and search:index) to the Rust engine, falling back seamlessly to JS for unsupported search-related tasks.

Migration

Zero. Existing configurations, plugins, and CI pipelines work unchanged.

Full changelog: https://github.com/docmd-io/docmd/compare/0.8.13...0.8.14