Changelog
All notable changes to DocsForge are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[10.9.1] — 2026-06-11
Fixed
CLI
--strictflag moved tobuildsubcommand — The--strictflag was previously defined on the basedocsforgegroup command, which was confusing since it only applied tobuild. Now it's only ondocsforge build --strictwhere it belongs.Streamlined
docsforge serveCLI — Removed unnecessary options:--no-openremoved — browser auto-open is harmless, always enabled--portremoved — automatically finds an available port starting from the configured one (e.g., 8000 → 8001 → 8002 if taken)--hostremoved — replaced with single--lanflag that binds to0.0.0.0for network access- New usage:
docsforge serve --lanto serve on all interfaces
[10.9.1] — 2026-06-11
Fixed
CLI
--strictflag moved tobuildsubcommand — The--strictflag was previously defined on the basedocsforgegroup command, which was confusing since it only applied tobuild. Now it's only ondocsforge build --strictwhere it belongs.Streamlined
docsforge serveCLI — Removed unnecessary options:--no-openremoved — browser auto-open is harmless, always enabled--portremoved — automatically finds an available port starting from the configured one (e.g., 8000 → 8001 → 8002 if taken)--hostremoved — replaced with single--lanflag that binds to0.0.0.0for network access- New usage:
docsforge serve --lanto serve on all interfaces
[10.9.0] — 2026-06-11
Added
Git revision dates — Every page now automatically shows "Last updated" and "Created" dates from git history. No configuration required — works out of the box for any docs site in a git repository. The dates are read from
git logand formatted as human-readable strings (e.g., "Jun 11, 2026"). The existingsource-file.htmltemplate already supported this — now it's actually populated. Disable withextra.git_revision_date: falsein docsforge.yml.CLI serve options — Added
--no-open,--port, and--hostflags todocsforge serve:docsforge serve --no-open # Don't auto-open browser docsforge serve --port 3000 # Serve on port 3000 docsforge serve --host 0.0.0.0 # Serve on all interfaces
Changed
- All theme features enabled by default — The material theme now enables a rich set of features out of the box, so new sites get the full experience without needing a long
features:list in docsforge.yml. New defaults include: content.action.edit,content.action.viewcontent.code.annotate,content.code.copycontent.tooltipsnavigation.footer,navigation.indexes,navigation.sections,navigation.tabs,navigation.top,navigation.tracking,navigation.instant,navigation.instant.progresssearch.highlight,search.share,search.suggesttoc.follow
[10.8.12] — 2026-06-11
Optimized
- Markdown instance reuse — Added per-thread caching of
markdown.Markdowninstances inpages.py. Previously, every page created a new Markdown instance, re-initializing all extensions (pymdownx, codehilite, etc.) from scratch. With 36 pages and 10+ extensions, this was a significant overhead. Now: - Each thread gets a cached Markdown instance keyed by
(extensions, configs) - Instances are
reset()between pages instead of recreated - Build time improvement: ~2.5s (was ~3.4s) — ~25% faster
Especially impactful for large sites with many Markdown extensions
Streamlined build.py — Multiple internal optimizations:
- Removed redundant
if _page_lock: with _page_lock:branching in_populate_page(it was always called sequentially, no lock needed) - Removed nested
_do_build()closure in_build_pagethat added function call overhead per page - Cached
files.documentation_pages()result instead of calling it 3 times per build - Moved
hashlibimport from inline (inside_inject_sw_build_hash) to module top level Simplified lock handling: always acquire lock in
_build_page, removedNonefallback pathRemoved "Cyrus" from copyright headers — Found and fixed 3 remaining files that still had "Cyrus" in the copyright string:
theme.py,preview.py,filter_config.py
[10.8.11] — 2026-06-08
Changed
- Lazy background caching — Replaced the blocking
cache.addAll()during service worker install with non-blocking incremental background caching. Previously, the SW tried to download all pages at once during install, which could block the initial page load. Now:
- The SW installs and activates immediately — the current page loads without delay.
- After activation, other pages are cached one by one in the background via
backgroundCachePages(). - The current page is already cached by the
fetchhandler when visited. - A
DOCSFORGE_CACHE_COMPLETEmessage is sent to all clients when done, so the UI can show a subtle indicator (e.g., "All pages available offline").
[10.8.10] — 2026-06-08
Fixed
- Service worker pre-cache URL resolution —
PRE_CACHE_PAGESURLs were relative to the site root (e.g.,"./","advanced/customization/"), butcache.addAll()inside the SW resolves URLs relative to the SW script location (/assets/javascripts/sw.js). This caused all pre-cache requests to fail silently, leaving the cache empty and breaking offline support. All pre-cache URLs now prefixed with../../so they correctly resolve from the SW to the site root. - Offline 404 fallback for subpath deployments —
cache.match("/404.html")was hardcoded to the domain root, which is wrong for sites deployed under a subpath (e.g.,/docsforge/). The SW now computesBASE_URLfrom its own location and usesBASE_URL + '404.html'for the fallback.
Added
- PWA update notification — When a new DocsForge version is deployed, the service worker activates and sends a
DOCSFORGE_UPDATE_READYmessage to all open tabs. The page displays a fixed banner at the top: "A new version of this documentation is available." with Refresh and Dismiss buttons. Users can click Refresh to immediately load the new content, or Dismiss to keep reading the current version. - Periodic update checks — The page checks for service worker updates every 5 minutes (
registration.update()), so users get notified of new content even on long-running sessions without needing to reload manually.
[10.8.9] — 2026-06-07
Added
- Full PWA / offline support — DocsForge now generates a
manifest.jsonand pre-caches all HTML pages during the service worker install phase, enabling full offline browsing of all documentation pages after the first visit. manifest.json— Generated automatically with site name, description, theme color (extracted from palette), and start URL. Linked via<link rel="manifest">in the<head>of every page.- Pre-caching all pages — The service worker now receives a
__PRE_CACHE_PAGES__placeholder that is replaced at build time with the complete list of all built HTML page URLs. Duringinstall, the SW caches every page so they work offline immediately without needing to visit each page first. - Cache-first strategy — The service worker now uses
cacheFirstWithNetworkFallbackfor HTML documents (wasstaleWhileRevalidatewhich caused network requests on every navigation). This means pages load instantly from cache even online, with a background update. - Offline fallback — If a page is not cached and the user is offline, the SW serves the 404 page (or a generic offline message if 404 isn't cached).
Changed
- Service worker strategy — Switched from
staleWhileRevalidatetocacheFirstWithNetworkFallbackfor HTML pages and assets. This prioritizes offline reliability and instant loads over always-fresh content. For most documentation sites, this is the desired behavior.
Fixed
- Removed "Cyrus" from all docs — Eliminated all remaining references to "Cyrus" from documentation, site footer, and copyright strings. The
license.mdanddocsforge.ymlsite author/copyright now use "QQ" only.
[10.8.8] — 2026-06-06
Changed
- Always dirty builds — Removed the
build_typeparameter fromserve()and alldirty=Falsedefaults. All builds are now incremental by default. Thedirtyflag was a legacy concept that caused confusion — full rebuilds are only triggered when the config file changes (detected by hash), andclean_directory+cache.invalidate()are skipped unless the config changes.
[10.8.7] — 2026-06-06
Fixed
docsforge servecache invalidation —DevServer.serve()was not passingbuild_type='dirty'toserve_module.serve(), causing the dev server to do full rebuilds with cache invalidation on every file change. This made live reload painfully slow. Thebuildcommand already did dirty/incremental builds by default; nowservedoes too.
[10.8.6] — 2026-06-06
Fixed
- Asset 404s on sub-pages —
base_urlcomputed byget_relative_url()returned..without trailing slash for pages at subdirectories. Without the trailing slash,_get_relative_urltreated it as a filename (stripped it), causing CSS/JS/asset paths to resolve relative to the page directory instead of the site root. Added trailing slash normalization toget_context()and_build_template().
[10.8.5] — 2026-06-06
Fixed
- Sidebar race condition — ThreadPoolExecutor parallel page builds caused multiple pages to be marked
activesimultaneously. EachPage.activesetter propagates to its parentSection, so concurrent builds leaked active state between pages. This resulted in the sidebar showing multiple sections as expanded when only the current section should be. Restructured_build_pageto hold the existingRLockfor the entire template render + file write phase, ensuring only one page is ever active at a time.
[10.8.4] — 2026-06-06
Fixed
- Search index 404 on non-root pages —
base_urlinbuild.pywas computed backwards:get_relative_url('.', page.url)returned the path from root to page instead of from page to root. The JS injected this into page config asbase, then resolvedsearch/search_index.jsonagainst it, producing a duplicated path like/docsforge/getting-started/getting-started/search/search_index.json. Fixed toget_relative_url(page.url, '.'). - Sidebar overlapping footer on desktop — Added
max-height: calc(100vh - 2.4rem)to.md-sidebar__scrollwrapatmin-width: 60emto prevent the sidebar from extending past the viewport and overlapping the footer.
[10.3.3] — 2026-05-17
Added
- Versioned service worker — Each build generates a unique hash in the SW, ensuring browsers install the new version and purge old caches
- Auto cache cleanup — Old caches automatically deleted when new SW activates
- Offline support — All same-origin files cached; HTML uses network-first, assets use cache-first
- PWA-ready — Service worker registration in every built page
Fixed
- Service worker scope set to
/(root) instead of/assets/javascripts/so it can intercept all requests
[10.3.2] — 2026-05-17
Fixed
- Service worker scope fixed to
/so it can cache blog posts and documentation pages - Added
request.mode === "navigate"check for better HTML page detection
[10.3.1] — 2026-05-17
Fixed
.icons/directory now included in PyPI wheel build- Added
artifactspattern inpyproject.tomlto ensure Material theme icons are packaged
[10.3.0] — 2026-05-17
Added
- TikZ diagram support — Write TikZ diagrams in Markdown, automatically compiled to SVG at build time
- Theme playground — Interactive palette switcher with live preview
- Blog plugin — Built-in blogging with authors, tags, archive, pagination, and RSS feeds
Fixed
- Source repo blank spot fixed (removed fixed 234px width when no stars/forks)
- Theme persistence across page navigation (uses
__md_scopeinstead of per-page URLs) - Palette toggle button highlight sync
- 404 page styling
Changed
- Cleaned up unrelated development files from repo
- All repos use
mainas default branch
[10.2.0] — 2026-05-16
Added
- Vendored mkdocs + Material — Self-contained, no external dependencies
- GitHub Pages deployment — GitHub Actions workflow for auto-deployment
- PyPI publishing — Automated releases via GitHub Actions
[10.1.0] — 2026-05-10
Added
- Zero-config Markdown — 31 extensions loaded by default (all pymdownx + python-markdown). No
markdown_extensions:config needed. - KaTeX math — Vendored KaTeX (1.5MB) renders
$$...$$inline and display math. No CDN calls for readers, no config. - Pygments highlighting — Syntax-colored code blocks at build time. No client-side JS.
- Dark mode toggle — Light/dark mode switch in header. Auto-detects system preference.
- Auto-loaded plugins — search, tags, blog, info, meta, minify, privacy all work without config.
- Self-hosted fonts — Privacy plugin downloads and caches Google Fonts locally.
Changed
- Config file renamed from
properdocs.ymltodocsforge.yml - Theme namespace changed from
mkdocs.themestodocsforge.themes - Plugin system — 6 plugins removed, 7 remain as built-in defaults
Removed
typeset— Users can write Unicode directlyoptimize— Requires externalpngquantbinarysocial— Requires Pillow + CairoSVGprojects— Niche multi-project featureoffline— Privacy plugin covers most use casesgroup— Plugin orchestrator (niche)
[0.1.0] — 2025-05-10
Added
- Initial release