Skip to content
docs-sitekit

Menu

Type to search the docs.

↑ ↓ move · Enter open · Esc close

Changelog

All notable changes to this project are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Changed

  • Every file is named in lowercase kebab-case, and the template imports its own layers through @/. SiteHeader.astro is now site-header.astro, buildDocuments.ts is build-documents.ts, src/presentation/sideCard/ is src/presentation/side-card/, in the template, the tests, the e2e specs and the scripts. Only the names of exports are CamelCase. Inside template/src/, an import that leaves its folder is @/infrastructure and not ../../infrastructure. A generated site changes in the same way, so this is a release that touches every file of a site. sitekit upgrade moves the files for you: a file you did not edit gets the new name and the new version, and a file you edited moves with your changes and the new version next to it to merge. A file of your own that imports a renamed file by its old name needs the new name. The FileSystem port of the CLI has a new remove, and the result of an upgrade has a new renamed list.

[0.2.4] - 2026-11-05

Added

  • A site can name the picture a shared link shows. The pages already said what they are with og:title and og:description, but gave no image, so a chat or a feed showed a bare link. Two new keys of site change it: image names a picture, a file in public/ such as /social.png or a full https address, and imageAlt is its alt text. With image set, every page has og:image, twitter:image and their alt text, and twitter:card is summary_large_image. Without it nothing changes: no picture, and summary. The kit draws no card and adds no dependency, so a generated site weighs what it did; social-card-action draws one in the style of the kit when you want it. The options page explains both keys, and the configuration reference lists them. Existing sites get the tags with sitekit upgrade, which replaces the layout.

[0.2.3] - 2026-11-04

Changed

  • The footer line names the site without the copyright sign and the year, and “Built with” links to the microsite. The legal line of the footer reads docs-sitekit · MIT licensed · v0.2.2, the name, then the license and the version, with no © and no year. The credit “Built with docs-sitekit” links to miguelcolmenares.com/docs-sitekit instead of the repository. The kit’s own site is named docs-sitekit in its sitekit.config.json. A generated site takes its name from package.json, the repository or the folder, as before. A site generated earlier gets this after SiteFooter.tsx and BaseLayout.astro are copied from this version, or with sitekit upgrade.
  • CodeQL also runs on every push to main. A scan of a pull request does not close an alert on main, so the eight alerts fixed by the previous change stayed open until the next Monday scan. The workflow now analyses main after each merge.

Fixed

  • Seven more CodeQL alerts, four of them polynomial regular expressions. absoluteUrl (in llms.ts, which every generated site carries), parseGitHubUrl, packageName and the link reader of check for llms.txt no longer use a pattern that tries again from every position, so a long run of one character stays linear. They have tests with long inputs. The test helper of the code block HTML tests now reads tags and entities in one pass, and the e2e test of reusable content escapes the version for a RegExp with every metacharacter. A site generated earlier gets the absoluteUrl fix after llms.ts is copied from this version, or with sitekit upgrade. The eighth alert, on the table cells of scripts/configReference.ts, is fixed in the next entry.

  • A pipe after a backslash no longer breaks a row of the generated configuration reference. A cell escaped a pipe with \| and left backslashes alone, so a description that already had \| became \\|, where GFM reads the first backslash as escaping the second and the pipe splits the cell into three (the last CodeQL alert, js/incomplete-sanitization). The backslashes right before a pipe are now doubled, and any other backslash, such as those of a pattern in a code span, stays single, so the page on disk does not change. It has a test that fails without the fix. This is repository tooling, not part of the template.

  • The search button and the doc layout pass axe at desktop width (#69). The search button had aria-label="Search", but from sm up its visible text is Search ⌘K, which fails Label in Name (WCAG 2.5.3). It has no aria-label now, and its name is the text Search: the word is visible from sm up, and it is hidden but still read on a phone, where the icon is the only thing shown. The two aside landmarks of the doc layout, the docs menu and the “On this page” list, had the same role and no name, which fails landmark-unique. They are divs now, because the nav in each one already has the name. The desktop axe check of the kit’s specs runs the WCAG 2.1 A and AA rules and the best practices, with no exemption, and any finding fails it. Two template tests read the markup of the button and the asides. A site generated earlier gets the fix after SiteHeader.astro and DocPage.astro are copied from this version, or with sitekit upgrade.

[0.2.2] - 2026-10-31

Changed

  • The Publish workflow creates the GitHub Release. After the package is on npm, a second job, the only one that can write to the repository, creates the Release for the tag with the matching section of the CHANGELOG as its notes, and does nothing if the Release already exists. A tag whose version has no section in the CHANGELOG fails that job. The Release no longer has to be made by hand.

  • A CodeQL workflow for this repository. .github/workflows/codeql.yml analyses the JavaScript and TypeScript of src/ and template/ on pull requests to main and every Monday, with the configuration of css-js-minifier. The actions are pinned by SHA.

Fixed

  • Three CodeQL warnings in code that every generated site carries, found when CodeQL analysed a site made by 0.2.0. parseCustomSvg removed comments in a single pass, which could leave a <!-- that the removal itself had closed up, so it now repeats until the text stops changing. The link text of llms.txt escaped brackets but not the backslash that could escape them, so a title ending in \ could break the link, and it now escapes both. The inline text reader of the search index took comments with ., which does not match a line break, and now takes them with [\s\S]. The first two have regression tests. A site generated earlier gets the fixes after customSvg.ts, buildLlmsText.ts and searchText.ts are copied from this version, or with sitekit upgrade.

[0.2.0] - 2026-10-30

Added

  • The site base is added to the links of nav and footer.links. A href that starts with / is a path of the site, and the build adds the base to it, in the header, in the menu of a phone and in the footer, as the buttons of the hero already did: with the base /acme/, /docs/getting-started/ becomes /acme/docs/getting-started/. Web addresses, //host addresses, mailto: links, # anchors, paths relative to the page and paths that already start with the base are left as written, so a site that wrote the base into its hrefs keeps working and a site served from / does not change. A path that starts with the base by accident is taken as complete: with the base /docs/, /docs/api/ stays /docs/api/, and /docs/docs/api/ reaches the page below it. The rule is the pure function withSiteBase in the domain layer of the template, with a unit test, a test with a real sitekit.config.json, and a browser spec on a generated site with the base /widget/ and a nav and footer.links (verify-package builds it a second time, and it is served on the port after the one of the project site). The warning on docs/options-navigation.md that asked for the base in each href is replaced by the rule. A site generated earlier gets this after BaseLayout.astro, domain/siteHref.ts and the line in domain/index.ts are copied from this version. See docs/options-navigation.md.
  • Guides for extending a site, each one run as a test. A new group, Extending your site, in the Docs of the project site: an index and six guides. An interactive page that is not markdown (a configurator with a form, a live preview and the generated hero key), a new collection with its own place in the menu and its own groups, a component you changed and what add and sitekit upgrade do to it, a new accent in design/tokens.json with a script that checks its contrast, a brand logo of your own and the layout of a collection, and what sitekit check looks for with a rule of your own under anonymize.denyPatterns. Each guide is a folder in e2e/recipes/ that has the layout of the repository. scripts/recipes.mjs applies it to a site made by init (a file is copied, site/sitekit.config.json is merged into the config, a .diff is applied with git apply), scripts/verify-package.mjs runs the commands the guide names with the real CLI and builds and checks the site, and e2e/specs/recipes.spec.ts drives it in Chromium. The configurator is tested at 320, 375 and 1280 px (no sideways scroll, targets of 44 px, a long line that scrolls inside its block), in both themes with measured contrast, without JavaScript, with no request to another host, and its output is compared with an expected text. The files a guide shows are copied from the folder by npm run build:docs (scripts/build-recipe-docs.mjs), and a test fails while a page is out of date. The guides add no package to the site: a check compares package.json and package-lock.json before and after. See docs/extending.md.
  • npm run build:tokens in a generated site. The script that turns design/tokens.json into src/styles/tokens.css is now scripts/build-tokens.mjs in the site, with --check to fail when the CSS is out of date, and the kit’s own script uses the same function. Until now only the repository of the kit had it, so a site owner who changed the tokens had no command to regenerate the CSS. A site generated earlier gets it after scripts/build-tokens.mjs is copied from this version and "build:tokens": "node scripts/build-tokens.mjs" is added to its package.json.
  • A page for each component, with a live preview, the code, the add command and its props. The new Components section of the project site (/components/<name>/) has 19 pages, from Button to PageInfo. Each has a preview of the real component drawn with the tokens of the site and a switch to see it in the other theme without leaving the page (the colors of each theme come from design/tokens.json under a data-preview-theme attribute, written by npm run build:tokens into a stylesheet that only the project site loads); the code that produced the preview, in a code block with its title and copy button, behind a Preview and Code tab control (tabs pattern, aria-selected, arrow keys, Home and End), and both shown one after the other without JavaScript; the command in a CommandBox, the files it writes and what it requires, each linked; a table of props with ReferenceTable; each variant and state as a preview of its own; and notes on keyboard use, target size and what is announced. Preview and code come from one file, template/src/examples/<name>/example.astro, which the page imports as a component and as text (?raw), so they cannot drift apart, and the copy button copies exactly that text. The tables are generated by scripts/build-component-docs.mjs (run by npm run build:docs) from the TypeScript types and TSDoc of the component, into template/src/examples/props.json: a prop with no description fails the script and is named, and a test fails while the file is out of date. Only the props the template declares are listed, not what a component takes from the DOM. The ten entries of the registry without a page, such as cn, the stock shadcn/ui primitives that no component uses, site-header and mobile-menu, are listed in docs/components.md each with its reason, and a test fails when an entry has neither a page nor a place in that list. docs/components.md is now the index of the section, a link to each page, and the text it had about StatRow, ReferenceTable and CatalogFilter moved to their pages. The registry has an optional example pointer that add ignores. The examples, the layout of the pages and the generated files are not in the package and not in a generated site (verify-package checks the tarball, a generated site and add), and the generated site has no new dependency and the pages make no request to another host. A collection can now have a layout of its own: a file named after its id in src/presentation/layouts/collections/ renders DocPage with more in its slot, and a site without that folder is not affected. The browser tests of the pages run against a build of the project site that verify-package makes, served on the port after the one of the generated site, at 320, 360, 390 and 1280 px: no sideways scroll, WCAG AA contrast in both themes (in the preview, in the other theme and in the code), 44 px controls, keyboard use of the tabs, and the copy button. See docs/components.md.
  • Mobile LCP under 2.5 s, and a font swap that moves nothing. The mobile menu is a native modal <dialog> and a short script, not a React sheet, so a page no longer downloads React and the Radix packages for a toggle (MobileMenu.tsx is now MobileMenu.astro, the layout renders it, and the registry entry follows). The layout preloads the Latin files of Geist and Geist Mono, and Geist Fallback and Geist Mono Fallback are local fonts scaled to Geist’s measures with size-adjust and the ascent, descent and line gap overrides, listed after the web font in design/tokens.json. On a site generated by init, in Lighthouse 12.6.1 mobile, three runs: LCP 2.86 to 3.00 s became 1.95 s, performance 93 to 94 became 99, and the page went from 337 KB to 152 KB. An inline stylesheet was measured and left out because it moved nothing. A browser test loads pages with the fonts 500 ms late and fails above a layout shift of 0.01 (e2e/specs/vitals.spec.ts, which reports the LCP element and its phases), and a CI job runs the public lighthouse package on the generated site against a budget for LCP, CLS, total blocking time and score, and uploads the reports. e2e/serve.mjs takes --compress and E2E_PORT picks the port of the browser tests. A site generated earlier gets this after it copies MobileMenu.astro, SiteHeader.astro, BaseLayout.astro, global.css and design/tokens.json and deletes MobileMenu.tsx. See docs/performance.md.
  • A configuration reference generated from the schema. npm run build:docs reads the config schema and writes docs/configuration.md: one table per group of sitekit.config.json, with the key, its type, its default, the values it allows and its description. Every key of the schema now has a .describe(), and the script fails and names the keys that have none, so a key cannot be added undocumented. A test compares the page with the schema and fails while it is out of date, and a second run of the script leaves no diff. The check group lists every kind of finding as its own row with its default severity, read from FINDING_KINDS, DEFAULT_SEVERITY and the new FINDING_DESCRIPTIONS, so a new kind cannot be left out. The hand-written tables of keys in docs/llms.md, docs/design-tokens.md and docs/edit-link.md, and the Default column of the kinds in docs/content.md, are replaced by links to the page, and the README links to it. Also a ReferenceTable component for a reference written in Astro: names in code, a type, a default, the values allowed and a text, inside a bordered region that scrolls sideways on a phone and takes keyboard focus (tabindex="0" in the HTML, with a name), with a caption and row headers. sitekit add reference-table restores it. A site generated earlier keeps its own copy of the template, so it gets the component after ReferenceTable.tsx is copied from this version. See docs/configuration.md and docs/components.md.
  • Brand logos: icon: "brand:<slug>" in the config. The kit ships 11 logos (Astro, Docker, GitHub, GitLab, Next.js, Node.js, npm, React, Tailwind CSS, TypeScript and Vercel) as path data, generated by npm run build:brands from simple-icons pinned to 16.36.0, a development dependency of the kit only. A logo is an inline SVG filled with currentColor, hidden from assistive technology unless Icon gets a label, and it asks nothing from any host, so a generated site has no new dependency. An unknown slug fails the build with the slug and the closest brands. The licence gate fails the script for an icon that is not CC0 unless it is on scripts/brands/allowlist.json with its licence, author and attribution, which then go to THIRD_PARTY_NOTICES.md; PHP (CC BY-SA 4.0) and AWS are not shipped. A logo the kit does not have is added as brands/<name>.svg next to the config and used as brand:custom/<name>; only plain <path> shapes are accepted. The header shows a repository button with the logo of the host (GitHub or GitLab, else a plain icon) and its name, 44 px tall, in the open menu on a phone, and the footer link has the logo too. A site generated earlier keeps its own copy of the template, so it gets this after Icon.tsx, the domain/brands folder, customBrands.ts, config.ts and the changes in loadSite.ts, SiteHeader.astro, MobileMenu.tsx, SiteFooter.tsx and BaseLayout.astro are copied from this version. See docs/brand-logos.md.
  • An “Edit this page” link and the date of the last change. The editLink key (enabled, branch, host) puts a link at the foot of every page to its source file on the repository host: {repository}/edit/{branch}/{path} on GitHub, with the GitLab and Bitbucket forms too. The host is found from site.repository, host is for a repository on a domain of its own, and an unknown host turns the link off with a message in the build and in sitekit check, never a broken address. The path includes the folder of the sources inside the git repository, so a site in a subfolder gets the right address. The lastUpdated key shows the date of the last commit that changed the file itself, read with git log at build time, as a <time datetime> element. In a shallow clone, or outside git, no dates are shown and the build says why, and sitekit check warns when the clone is shallow. The link is a 44 px target and the line reaches WCAG AA in both themes. sitekit init turns both on for a new site and writes fetch-depth: 0 in the workflow it generates. A site without the keys does not change, and sitekit upgrade adds both with enabled: false. The component is PageInfo, and sitekit add page-info restores it. A site generated earlier gets the line after PageInfo.tsx, DocPage.astro, loadSite.ts, gitHistory.ts, buildPageMeta.ts, editLink.ts, lastUpdated.ts and the change in config.ts are copied from this version. See docs/edit-link.md.
  • Variables and shared snippets in Markdown. {{ version }} in prose, headings, link text and the frontmatter is replaced when the site is built, with the version of the repository’s package.json or a value from the new vars key of sitekit.config.json (string values, and vars wins). In code spans and fenced code it is left as written. A snippet is a file under snippets/ included with <!-- include: name.md --> alone on a line: the indentation of the comment goes in front of each line, so it works inside a list item, it goes one level deep, and the folder is not published as pages. The replacement happens first, when the content is read, so the title, the description, the search index, llms.txt and the Markdown copies show the replaced text. An unknown variable is a variables finding, a warning, and a missing snippet a snippets finding, an error, both with the file and line, in the build and in sitekit check, and both follow check in the config. A page that uses neither feature is not touched. GitHub shows {{ version }} as literal text and hides the include comment. See docs/content.md.
  • A detail layout with a side card of metadata. A page with meta (a list of label and value), links (a list of label and href) and tags in its frontmatter shows a card beside its text, with no new data format. On a desktop (lg and up) the card is on the right and stays in view while the text scrolls, and it takes the place of the table of contents. On a phone it is under the title and above the text, collapsed to its first three rows, with an “All details” button that has aria-expanded and a 44 px target. Without JavaScript the whole card is shown and the button is not. The metadata is a <dl>, the links are real links resolved like the links in the text (a page becomes its route, a file of the repository becomes its address, a link to a missing or excluded file is left out), and a long value wraps. A page with only tags, such as an index with a filter bar, and a page with none of the three, do not change. The SideCard component takes its data through props and imports no content, and sitekit add side-card restores it. What the card’s frontmatter got wrong is a new kind of finding, card, an error by default and configurable under check like the others: a key the card does not read (lable for label), an item without text, a meta or links that is not a list, and a link with a scheme other than http:, https: or mailto:. sitekit check and the build print it with the file and the line of the key in the frontmatter, and check exits with 1. A link of the card to a file that is missing or excluded is a links or excludedLinks finding, like the same link in the text. meta and links are now keys that the frontmatter check knows. A site generated earlier keeps its own copy of the template, so it gets the card after DocPage.astro, document.ts, findings.ts, buildDocuments.ts, validateContent.ts, loadSite.ts and the files of side-card are copied from this version. See docs/detail-page.md.
  • A filter bar for the index pages. A page can have tags in its frontmatter, a list or a comma separated string. When any page of an index has a tag, the index shows a text field and one toggle button per tag above its cards. The cards that do not match get the hidden attribute, a polite status line says “N of M shown.”, and a state with no match says so and offers “Clear filter”. The state is in the address, ?tag=ui&q=card, so a filtered view can be shared and the back button works. Without JavaScript every card is shown and the bar is hidden, and an index without tags does not change. The controls are 44 px high, with aria-pressed on the tags. The matching is a pure function in the domain layer, and sitekit add catalog-filter restores the files. A site generated earlier keeps its own copy of the template, so it gets the bar after Document.tags, buildDocuments.ts, CollectionIndex.astro, ItemCard.tsx and the files of catalog-filter are copied from this version. See docs/components.md.
  • Code blocks with a title, highlighted lines, diff lines and a copy button. The options go after the language in the fence, which GitHub ignores: ts title="src/config.ts" {2,4-6}. A title is a caption bar over the block. The lines in the braces have a tone and a bar on their left edge. A line that ends with a [!code ++] or [!code --] comment, or a line of a diff block that starts with + or -, is shown as added or removed, with a sign as well as a tone, so color is not the only cue. The markers are taken out of the code. Every block has a copy button, a real button named “Copy code” with a 44 px target and a focus ring, that copies the text of the code (not the markers, and not the signs drawn in the margin) and says “Copied” in a polite status region. The button is written hidden and shown by a script of about 540 bytes that ships in the page and makes no request, so without JavaScript the block still reads. A long line scrolls inside the block, and a block with no options looks as it did. It is built on the Shiki transformers of the markdown package, so there is no new dependency. The tones are three new color tokens in both sets, code-highlight, code-add and code-remove, and the contrast tests check them against every token color of both code themes. A site generated earlier keeps its own copy of the template, so it draws these blocks only after the files that docs/code-blocks.md lists are copied from this version. See docs/code-blocks.md.
  • A StatRow component for a few numbers with their labels. Two to five items, each a value, a label and an optional note, as a description list so the label and the value are read together. The value is the large text in the mono face and wraps when it is long. The grid has explicit tracks, one column on a phone, and it chooses no status color. The home page shows it when sitekit.config.json has a stats key (two to five items, or none), and a site without the key does not change. sitekit add stat-row restores it. See docs/components.md.
  • Search. A header button, Ctrl K or Cmd K, and the slash key open a dialog that searches the title, headings and text of every page, and opens the section that matched. The search code and the index load on first use, and search.enabled in the config turns it off. sitekit check verifies that the index lists every page. Typo tolerance is not in this version.
  • A light theme, with a switch in the header. The site stays dark by default. theme.default in sitekit.config.json takes dark, light or system, and an invalid value fails the build with the key named. A visitor’s choice is saved in the browser and wins over the default, and the theme is applied before the first paint. The light set is a second set of colors in design/tokens.json, with the same keys as the dark one, and a test fails when the keys differ. Code blocks have a light highlighter theme. A site generated with an earlier version keeps its own design/tokens.json, which has no light set, so it stays dark until it adds one.
  • An llms key for llms.txt. With enabled, the site writes llms.txt at its base: an H1 with the name, the description, one H2 per collection with absolute links and descriptions, and ## Optional for the collections listed in optional. With markdownPages, each page also has a Markdown copy at its address with index.html.md after it, and the page links to it. sitekit init turns it on for a new site, and a site without the key does not change. It is a community proposal, not a search feature. See docs/llms.md.
  • sitekit check verifies llms.txt when it is on: the H1, every link, every page listed, the Markdown copies, and the credential and internal host scan.
  • Callouts written in markdown. A blockquote that starts with > [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING] or > [!CAUTION] on its own line becomes a callout, the alert syntax that GitHub renders too. It is plain HTML with role="note", a hidden icon and a visible label, so it needs no JavaScript, and the tones come from the existing color tokens. A callout can hold paragraphs, lists and code, and can sit in a list item. A blockquote without a marker, an unknown marker such as [!NOTES], and a marker in code are left as they are. The Callout component has the same five kinds, role="note" and a colored left edge, and the docs have a new page, Callouts. A site generated earlier keeps its own copy of the template, so it renders callouts only after callouts.ts, calloutIcons.ts, remarkCallouts.ts, the change in renderMarkdown.ts and the callout styles of prose.css are copied from this version. See docs/callouts.md.
  • sitekit upgrade, to bring a generated site up to the installed kit. For each file in site/.sitekit.json it compares your file, the version it was written from (by hash) and the kit’s file. A file you did not edit and the kit changed is replaced. A file you edited and the kit did not change is kept. A file you edited and the kit changed is left as it is, with the new version written next to it as <file>.sitekit-new, so your file is never lost. A file that is new in the kit is added. --dry-run prints the report and writes nothing, and the upgrade is a dry run by default when the working tree has uncommitted changes, unless you pass --apply. It never writes docs/, your other content, the deploy workflow or files that are not in the lock, and it adds only the options that do not exist yet to sitekit.config.json (theme, search, llms), with the value that keeps the site as it was. The lock is rewritten for the files that were replaced or added. The package name and description of a site are kept. See docs/upgrading.md.
  • Content findings in sitekit check and in the build. The markdown is read as data and each problem is reported as docs/guide.md:42: warning: ..., with a severity, the file and the line of the link, image, heading or key: a relative link to a file that does not exist or that you excluded, a link to a heading that is not in the target page, an image that does not exist, a frontmatter key the kit does not read, an order that is not a number, two headings that make the same anchor, and an unknown callout marker such as [!NOTES]. check counts them and exits with 1 on any error, the build prints them and does not fail. A missing image and a bad order are errors, the rest warnings, and the new check key in sitekit.config.json sets each kind to error, warning or off; a name that is not a kind fails with the name in the message. Links, images, headings and markers inside code are never reported. The warnings that loadSite collected while rendering, and that nothing printed, are replaced by these findings. A site generated earlier gets the findings in check at once, because the CLI reads them, and in the build once it copies the changed files of template/src/ and astro.config.ts from this version. See docs/content.md.
  • Options by topic, with examples. Eight new pages in the documentation: an index and one page each for identity and the home page, navigation and collections, theme and design, search and llms.txt, content checks and publishing, the edit link and dates, and brand logos. Each group of keys has a sitekit.config.json example and says what it changes on the built site, found by building a site with that key. The keys stay documented once, in the generated configuration reference, and the topic pages link to it. A test reads the schema and fails for every key that no example shows, one test checks each example against the real schema, and one fails when a page repeats a row or a description of the generated reference. Two more tests fail when a message quoted on a page, or a finding shown in the table of the checks page, is not the one the code prints. A new end to end spec reads the facts of the default site on the generated site. The table of the kinds of finding in docs/content.md is replaced by links, because the reference already lists them. The documentation site keeps two example texts on its anonymize.allow list, since the checks page shows them. See docs/options.md.

Changed

  • The project site announces https://miguelcolmenares.com/docs-sitekit/ as its address, in its canonical links, its sitemap and its llms.txt. The personal domain serves the site through a proxy, and GitHub Pages keeps answering at the old address. A site generated with init is not affected.
  • The default accent is the VS Code blue: accent #4fc1ff, accent-strong #007acc and accent-contrast #ffffff, in place of the purple. A site generated with init takes the blue from the kit it is generated with. A site generated earlier keeps its own design/tokens.json, so it stays purple until its owner changes that file.
  • The Action’s Marketplace icon is blue, branding.color in action.yml, to match the new default accent. Blue is the closest color the Marketplace offers to the VS Code blue.

Fixed

  • Four things the component pages measured in the components themselves. The destructive Button was white on the danger color, 3.52:1 in the dark theme and 2.77:1 in the light one, and now takes the page color on it. The outline Button had a shadow, against the rule of 1 px borders. The command of a CommandBox scrolls sideways without a scroll bar and could not be reached with the keyboard, so it takes focus (tabindex="0"), as every scrollable region does. The contrast meter of the browser tests left out the text of a disabled control, as WCAG 1.4.3 does, and its own test covers that. A site generated earlier gets the first three after button.tsx and CommandBox.tsx are copied from this version.
  • The name of the tool is docs-sitekit everywhere a reader sees it. The footer of every generated site, the Action address, its name, the issue forms, the contributing steps and the help text used the old short name. The sitekit command and the file names do not change. A test reads these texts and fails on the old name. The Action address in the 0.1.0 notes is corrected too.

[0.1.1] - 2026-10-28

Fixed

  • Two CodeQL findings in describe.ts, the file that turns markdown into titles and descriptions and that every generated site carries. Removing HTML tags in a single pass left a <script behind when tags were nested, so tags are now removed until the text stops changing. The check for a row of badges used a nested repetition that could backtrack exponentially on a long run of badge-like text, and now removes each badge with a single pattern. Both have regression tests. A site generated with 0.1.0 can copy describe.ts from this version.
  • The project site is served under /docs-sitekit/, where it was still asking for its assets under the old repository name. A test now ties the site’s base path, address and repository to package.json.

[0.1.0] - 2026-10-28

First release. The package is docs-sitekit and the action is miguelcolmenares/docs-sitekit. The sitekit command is the one you run: npx docs-sitekit init.

Added

  • sitekit init, check, list and add. init reads package.json and the git remote, finds docs/, docs/tutorials/, docs/examples/ and examples/, writes the site and a GitHub Pages workflow, and refuses a folder that already has files.
  • Collections and groups. A site has any number of collections (Docs, Tutorials, Examples). A page belongs to the collection with the deepest folder, so docs/tutorials/ can sit inside docs/. Pages can be put in groups with a tone, and a page that is in no group, or a group that names a page that does not exist, fails the build instead of being skipped.
  • A reusable GitHub Action (miguelcolmenares/docs-sitekit) that installs, builds and checks a site and uploads it as the Pages artifact. The workflow init writes uses it and rebuilds the site when a release is published. Deploying stays in a separate job.
  • A dark design system on Astro, Tailwind, shadcn/ui and lucide-react: tokens, header, hero, section headers, cards, feature grid, flow diagram, command table, callouts, footer, doc layout with table of contents, and copy buttons. Tokens come from one file, and contrast is tested on them.
  • A content pipeline that turns markdown into pages, derives titles and descriptions without being fooled by badges, tables or code fences, rewrites relative links, and fails on two files that would get the same route.
  • The version in the footer is read from the repository’s package.json on every build, so a site rebuilt for a release shows the release.
  • A publish check, sitekit check: credentials and internal hosts in the content and in the built files, the repository’s visibility (a private repository’s Pages site is public), and the shape of the output, including a 404.html that is not a copy of index.html.
  • Pack-and-install verification, and Playwright tests on a phone (320, 360 and 390 px) and a desktop: WCAG AA contrast measured in the browser, touch targets, scrollable code blocks and tables that can be focused, no horizontal scroll, keyboard use, and accessibility checks.
  • Security policy, contributing guide, issue and pull request templates, and third-party notices.
Edit this page

Last updated