mdcms build now calls generate_site_manifest() at the end of every build,
writing mdcms.json to the site root. This file lists all deployable files
and empty directories, and is deployed alongside the site so any mdcms
user can register a copy of the site from its URL.
mdcms register now accepts a GitHub repo URL or plain HTTPS URL as PATH
or via --from. GitHub URLs try mdcms.json (raw content) first and fall
back to the Contents API tree-walk. Plain URLs require mdcms.json to be
present and fail with a clear error if it is not found.
- generate_site_manifest() added; called at end of run_build
- download_template(dest, source=None) dispatches on source type
- _parse_github_url() extracts owner/repo/branch/subpath from GitHub URLs
- _fetch_manifest() / _apply_manifest() handle the manifest protocol
- _download_tree_api() retained as GitHub Contents API fallback
- _http_get_github() carries Accept header for Contents API responses
- MANIFEST_FILENAME = "mdcms.json"; GITHUB_URL_RE added
- app/template-manifest.json replaced by app/mdcms.json
- register command: PATH accepts URL; --from option added
https://claude.ai/code/session_01Ai8xRvmrzdhuTKiRQ2fnn9
Replace the GitHub Contents API tree-walk with a flat manifest approach.
template-manifest.json lists every file and empty directory in the starter
template; download_template() fetches the manifest then pulls each file
directly as a raw URL, sidestepping git API rate limits and making the
template hostable from any HTTP source.
- GITHUB_CONTENTS_API / _github_get / _download_tree removed
- TEMPLATE_BASE_URL + TEMPLATE_MANIFEST constants added
- _http_get() replaces _github_get() (generic, no GitHub headers)
- download_template() accepts optional base_url for custom sources
- app/template-manifest.json added (v0.4, 35 files, 2 empty dirs)
- Generated files (manifest.json, service-worker.js, search.json)
excluded from manifest — they belong to mdcms build output, not
the starter template
https://claude.ai/code/session_01Ai8xRvmrzdhuTKiRQ2fnn9
Pages whose filename matches a nav section-id now get a clean pathname
URL (e.g. /timesheet) instead of the hash-based /#pages/timesheet.md.
- _initialPathname captured at IIFE start; handles ?_route= from 404.html
- basePath determined by initBasePath() after nav data loads; subpath
deployments (e.g. /mysite/) handled automatically
- navigateTo() uses replaceState to /slug for section-id pages and falls
back to #hash for everything else
- popstate listener handles browser history if a clean URL was the entry
- resolveSlugToFile() validates that slug is both a section code and has
a pages/{slug}.md entry in navData
- app/404.html added for GitHub Pages SPA routing
https://claude.ai/code/session_01Ai8xRvmrzdhuTKiRQ2fnn9
Documents all four block types (tab-underline, tab-filled,
accordion-underline, accordion-filled and their aliases) with
per-item key tables and worked examples, in the same style as
the existing callout/toc/posts-* sections.
https://claude.ai/code/session_01SFMh7PDxJjvvo5dYbCCFFs
Implements four new mdcms fenced-block types:
tab-underline / tab, tab-filled,
accordion-underline / accordion, accordion-filled
Each block reads items: from a YAML body. Tab state and accordion
open/close are managed with aria-selected / aria-expanded and
data-open attributes. Markdown content inside each item is rendered
with the same pipeline as the surrounding page.
Adds computeDerivedTokens() — called on every applyTheme() — which
computes --mdcms-bar, --mdcms-filled-bg/border/fg, --mdcms-strip-border
from the active palette. Uses HSL chroma (S × (1-|2L-1|)) instead of raw
HSL S for the bold-nav heuristic, avoiding a false-positive on near-white
nav colours like the default #F8FAFC.
Adds app/pages/tabs-accordions.md as a visual test page and
docs/unreleased.md to track this change ahead of the next release.
https://claude.ai/code/session_01SFMh7PDxJjvvo5dYbCCFFs
When set to visible, the category always appears in the selector
even when no variant exists for the current page. Navigating to
such a page shows pagenotfoundmessage with no fallback to
default-category content. Default behaviour (hidden) is unchanged.
Updates pageShouldDisplay and visibleCategoryCodesForCurrentPage
to honour the new key alongside the existing notfoundmessage logic.
Docs updated with key description, summary table, and full example.
Documents all keys that can appear under default-category and
categories entries: message, name-latin, notfoundmessage,
pagenotfoundmessage, font, and line-height. Adds a summary table
and updates the full example to show these keys in context.
fetchPageFile now rejects text/html responses so servers with SPA routing
(e.g. Cloudflare Pages with /* /index.html 200) no longer trick the renderer
into treating a fallback index.html as a found markdown file. Category-variant
pages (page.current.md with no plain page.md) now fall through correctly to
their variant URL.
mdcms build now writes a self-unregistering service-worker.js when pwa: no,
evicting any stale caching worker left over from a previous pwa: yes build.
manifest.json is also removed when pwa: no.
https://claude.ai/code/session_01Xs5GyREFhjWxhS1UhW2wA8
A YAML parse error in config.yml (e.g. a stray tab character) caused
read_config to swallow the exception and return {}, disabling categories
and producing a broken nav.yml with no variants fields and wrong filenames.
read_config now raises ClickException on both OSError and YAMLError.
Documented in docs/knownbugs.md and docs/unreleased.md.
https://claude.ai/code/session_01Xs5GyREFhjWxhS1UhW2wA8
mdcms build now writes the sitename from config.yml into the <title> tag
of index.html. WhatsApp, Slack, and other link-preview crawlers read the
static HTML without executing JavaScript, so the title must be correct in
the raw file. Previously it was blank (or "MD-CMS" in older templates).
Pages without a category suffix still map to the default category.
Only posts/ files without a suffix get uncategorized: true in nav.yml
and category: null in search.json.
https://claude.ai/code/session_01EzU13EL8D5Ud2ngQUKDj9e
Two new top-level theme.yml keys — nav-section-expand-icon and
nav-section-collapse-icon — replace the hardcoded arrow_right/arrow_drop_down
used on collapsible nav sections. Defaults preserve existing behaviour.
Eight new icon SVGs added to app/assets/icons/:
keyboard_arrow_right / keyboard_arrow_down (chevrons)
keyboard_double_arrow_right / keyboard_double_arrow_down
expand_content / collapse_content (corner arrows)
add / minimize (plus/minus)
All eight added to STANDARD_ICONS so fetch-deps bundles them correctly.
CLAUDE.md key reference and docs/claude-design.md updated with the full
icon catalogue, pairing guidance, and style notes for Claude Design.
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
Documents every colour pairing to check, WCAG contrast targets for each
role, and common failure modes (saturated accents, muted text on tinted
backgrounds, dark-mode text-muted). Checklist expanded with contrast items.
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
Separates sidebar header colours from nav link colours. The three new keys
control the site name, site description, and dark/light toggle independently,
each cascading from the nearest nav variable (nav-sitename → nav-link,
nav-description and nav-toggle → nav-section-heading) so existing themes
are unaffected.
Enables Claude Design to fine-tune sidebar header legibility on saturated or
bold nav backgrounds without having to override the nav link colours, and vice
versa. CSS selectors and applyThemeYml() updated; app/theme.yml, CLAUDE.md,
and docs/claude-design.md updated with full key reference and pattern examples.
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
Clarifies that nav-link, nav-link-active, and nav-section-heading affect not
just nav links but also the site name, description, and theme toggle — all
sidebar elements that inherit from these variables. Adds a rule of thumb for
when to set the keys explicitly (saturation >20%, or lightness outside the
neutral range).
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
--divider in both light and dark modes now auto-derives from the theme's
background and text colours using color-mix(in srgb, bg 85%, text), so
accent-coloured or custom-background themes get a correct divider without
any extra config. An explicit `divider` key in theme.yml overrides this
for the rare cases where exact control is needed.
docs/claude-design.md and CLAUDE.md updated accordingly.
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
- New theme.yml keys: nav-link, nav-link-active, nav-section-heading (per
light/dark mode). Fixes themes where nav-background equals accent, which
made active nav links invisible against their own background.
- New colours-semantic-dark block overrides callout semantic colours in dark
mode only, preventing washed-out callout borders and backgrounds on dark
page backgrounds.
- CSS: nav item and section heading selectors now use the new CSS variables
with graceful fallbacks to existing defaults — no breakage for themes that
don't set the new keys.
- app/theme.yml starter updated with new keys (commented examples) and
sensible colours-semantic-dark defaults.
- CLAUDE.md updated with full key reference table and guidance on when to
use nav colour overrides.
- docs/claude-design.md: new authoring guide for Claude Design covering
contrast rules, nav pattern examples, and a pre-publish checklist.
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
Updated GitHub Actions workflow to include permissions and modified installation command for mdcms. Changed directory handling for building sections to use a loop instead of hardcoded values.
This guide provides detailed steps for releasing a new version of mdcms, including prerequisites, setup, version bumping, tagging, and monitoring the build process.