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.astrois nowsite-header.astro,buildDocuments.tsisbuild-documents.ts,src/presentation/sideCard/issrc/presentation/side-card/, in the template, the tests, the e2e specs and the scripts. Only the names of exports are CamelCase. Insidetemplate/src/, an import that leaves its folder is@/infrastructureand not../../infrastructure. A generated site changes in the same way, so this is a release that touches every file of a site.sitekit upgrademoves 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. TheFileSystemport of the CLI has a newremove, and the result of an upgrade has a newrenamedlist.
[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:titleandog:description, but gave no image, so a chat or a feed showed a bare link. Two new keys ofsitechange it:imagenames a picture, a file inpublic/such as/social.pngor a fullhttpsaddress, andimageAltis its alt text. Withimageset, every page hasog:image,twitter:imageand their alt text, andtwitter:cardissummary_large_image. Without it nothing changes: no picture, andsummary. 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 withsitekit 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 nameddocs-sitekitin itssitekit.config.json. A generated site takes its name frompackage.json, the repository or the folder, as before. A site generated earlier gets this afterSiteFooter.tsxandBaseLayout.astroare copied from this version, or withsitekit upgrade. - CodeQL also runs on every push to
main. A scan of a pull request does not close an alert onmain, so the eight alerts fixed by the previous change stayed open until the next Monday scan. The workflow now analysesmainafter each merge.
Fixed
-
Seven more CodeQL alerts, four of them polynomial regular expressions.
absoluteUrl(inllms.ts, which every generated site carries),parseGitHubUrl,packageNameand the link reader ofcheckforllms.txtno 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 aRegExpwith every metacharacter. A site generated earlier gets theabsoluteUrlfix afterllms.tsis copied from this version, or withsitekit upgrade. The eighth alert, on the table cells ofscripts/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 fromsmup its visible text isSearch ⌘K, which fails Label in Name (WCAG 2.5.3). It has noaria-labelnow, and its name is the textSearch: the word is visible fromsmup, and it is hidden but still read on a phone, where the icon is the only thing shown. The twoasidelandmarks of the doc layout, the docs menu and the “On this page” list, had the same role and no name, which failslandmark-unique. They aredivs now, because thenavin 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 afterSiteHeader.astroandDocPage.astroare copied from this version, or withsitekit 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.ymlanalyses the JavaScript and TypeScript ofsrc/andtemplate/on pull requests tomainand 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.
parseCustomSvgremoved 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 ofllms.txtescaped 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 aftercustomSvg.ts,buildLlmsText.tsandsearchText.tsare copied from this version, or withsitekit upgrade.
[0.2.0] - 2026-10-30
Added
- The site base is added to the links of
navandfooter.links. Ahrefthat starts with/is a path of the site, and the build adds thebaseto 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,//hostaddresses,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 functionwithSiteBasein the domain layer of the template, with a unit test, a test with a realsitekit.config.json, and a browser spec on a generated site with the base/widget/and anavandfooter.links(verify-packagebuilds it a second time, and it is served on the port after the one of the project site). The warning ondocs/options-navigation.mdthat asked for the base in eachhrefis replaced by the rule. A site generated earlier gets this afterBaseLayout.astro,domain/siteHref.tsand the line indomain/index.tsare copied from this version. Seedocs/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
herokey), a new collection with its own place in the menu and its own groups, a component you changed and whataddandsitekit upgradedo to it, a new accent indesign/tokens.jsonwith a script that checks its contrast, a brand logo of your own and the layout of a collection, and whatsitekit checklooks for with a rule of your own underanonymize.denyPatterns. Each guide is a folder ine2e/recipes/that has the layout of the repository.scripts/recipes.mjsapplies it to a site made byinit(a file is copied,site/sitekit.config.jsonis merged into the config, a.diffis applied withgit apply),scripts/verify-package.mjsruns the commands the guide names with the real CLI and builds and checks the site, ande2e/specs/recipes.spec.tsdrives 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 bynpm 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 comparespackage.jsonandpackage-lock.jsonbefore and after. Seedocs/extending.md. npm run build:tokensin a generated site. The script that turnsdesign/tokens.jsonintosrc/styles/tokens.cssis nowscripts/build-tokens.mjsin the site, with--checkto 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 afterscripts/build-tokens.mjsis copied from this version and"build:tokens": "node scripts/build-tokens.mjs"is added to itspackage.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, fromButtontoPageInfo. 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 fromdesign/tokens.jsonunder adata-preview-themeattribute, written bynpm run build:tokensinto 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 aCommandBox, the files it writes and what it requires, each linked; a table of props withReferenceTable; 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 byscripts/build-component-docs.mjs(run bynpm run build:docs) from the TypeScript types and TSDoc of the component, intotemplate/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 ascn, the stock shadcn/ui primitives that no component uses,site-headerandmobile-menu, are listed indocs/components.mdeach with its reason, and a test fails when an entry has neither a page nor a place in that list.docs/components.mdis now the index of the section, a link to each page, and the text it had aboutStatRow,ReferenceTableandCatalogFiltermoved to their pages. The registry has an optionalexamplepointer thataddignores. The examples, the layout of the pages and the generated files are not in the package and not in a generated site (verify-packagechecks the tarball, a generated site andadd), 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 insrc/presentation/layouts/collections/rendersDocPagewith 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 thatverify-packagemakes, 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. Seedocs/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.tsxis nowMobileMenu.astro, the layout renders it, and the registry entry follows). The layout preloads the Latin files of Geist and Geist Mono, andGeist FallbackandGeist Mono Fallbackare local fonts scaled to Geist’s measures withsize-adjustand the ascent, descent and line gap overrides, listed after the web font indesign/tokens.json. On a site generated byinit, 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 publiclighthousepackage on the generated site against a budget for LCP, CLS, total blocking time and score, and uploads the reports.e2e/serve.mjstakes--compressandE2E_PORTpicks the port of the browser tests. A site generated earlier gets this after it copiesMobileMenu.astro,SiteHeader.astro,BaseLayout.astro,global.cssanddesign/tokens.jsonand deletesMobileMenu.tsx. Seedocs/performance.md. - A configuration reference generated from the schema.
npm run build:docsreads the config schema and writesdocs/configuration.md: one table per group ofsitekit.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. Thecheckgroup lists every kind of finding as its own row with its default severity, read fromFINDING_KINDS,DEFAULT_SEVERITYand the newFINDING_DESCRIPTIONS, so a new kind cannot be left out. The hand-written tables of keys indocs/llms.md,docs/design-tokens.mdanddocs/edit-link.md, and the Default column of the kinds indocs/content.md, are replaced by links to the page, and the README links to it. Also aReferenceTablecomponent 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-tablerestores it. A site generated earlier keeps its own copy of the template, so it gets the component afterReferenceTable.tsxis copied from this version. Seedocs/configuration.mdanddocs/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 bynpm run build:brandsfromsimple-iconspinned to 16.36.0, a development dependency of the kit only. A logo is an inline SVG filled withcurrentColor, hidden from assistive technology unlessIcongets alabel, 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 onscripts/brands/allowlist.jsonwith its licence, author and attribution, which then go toTHIRD_PARTY_NOTICES.md; PHP (CC BY-SA 4.0) and AWS are not shipped. A logo the kit does not have is added asbrands/<name>.svgnext to the config and used asbrand: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 afterIcon.tsx, thedomain/brandsfolder,customBrands.ts,config.tsand the changes inloadSite.ts,SiteHeader.astro,MobileMenu.tsx,SiteFooter.tsxandBaseLayout.astroare copied from this version. Seedocs/brand-logos.md. - An “Edit this page” link and the date of the last change. The
editLinkkey (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 fromsite.repository,hostis for a repository on a domain of its own, and an unknown host turns the link off with a message in the build and insitekit 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. ThelastUpdatedkey shows the date of the last commit that changed the file itself, read withgit logat build time, as a<time datetime>element. In a shallow clone, or outside git, no dates are shown and the build says why, andsitekit checkwarns when the clone is shallow. The link is a 44 px target and the line reaches WCAG AA in both themes.sitekit initturns both on for a new site and writesfetch-depth: 0in the workflow it generates. A site without the keys does not change, andsitekit upgradeadds both withenabled: false. The component isPageInfo, andsitekit add page-inforestores it. A site generated earlier gets the line afterPageInfo.tsx,DocPage.astro,loadSite.ts,gitHistory.ts,buildPageMeta.ts,editLink.ts,lastUpdated.tsand the change inconfig.tsare copied from this version. Seedocs/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’spackage.jsonor a value from the newvarskey ofsitekit.config.json(string values, andvarswins). In code spans and fenced code it is left as written. A snippet is a file undersnippets/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.txtand the Markdown copies show the replaced text. An unknown variable is avariablesfinding, a warning, and a missing snippet asnippetsfinding, an error, both with the file and line, in the build and insitekit check, and both followcheckin the config. A page that uses neither feature is not touched. GitHub shows{{ version }}as literal text and hides the include comment. Seedocs/content.md. - A detail layout with a side card of metadata. A page with
meta(a list oflabelandvalue),links(a list oflabelandhref) andtagsin its frontmatter shows a card beside its text, with no new data format. On a desktop (lgand 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 hasaria-expandedand 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 onlytags, such as an index with a filter bar, and a page with none of the three, do not change. TheSideCardcomponent takes its data through props and imports no content, andsitekit add side-cardrestores it. What the card’s frontmatter got wrong is a new kind of finding,card, an error by default and configurable underchecklike the others: a key the card does not read (lableforlabel), an item without text, ametaorlinksthat is not a list, and a link with a scheme other thanhttp:,https:ormailto:.sitekit checkand the build print it with the file and the line of the key in the frontmatter, andcheckexits with 1. A link of the card to a file that is missing or excluded is alinksorexcludedLinksfinding, like the same link in the text.metaandlinksare now keys that thefrontmattercheck knows. A site generated earlier keeps its own copy of the template, so it gets the card afterDocPage.astro,document.ts,findings.ts,buildDocuments.ts,validateContent.ts,loadSite.tsand the files ofside-cardare copied from this version. Seedocs/detail-page.md. - A filter bar for the index pages. A page can have
tagsin 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 thehiddenattribute, 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, witharia-pressedon the tags. The matching is a pure function in the domain layer, andsitekit add catalog-filterrestores the files. A site generated earlier keeps its own copy of the template, so it gets the bar afterDocument.tags,buildDocuments.ts,CollectionIndex.astro,ItemCard.tsxand the files ofcatalog-filterare copied from this version. Seedocs/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 adiffblock 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-addandcode-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 thatdocs/code-blocks.mdlists are copied from this version. Seedocs/code-blocks.md. - A
StatRowcomponent 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 whensitekit.config.jsonhas astatskey (two to five items, or none), and a site without the key does not change.sitekit add stat-rowrestores it. Seedocs/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.enabledin the config turns it off.sitekit checkverifies 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.defaultinsitekit.config.jsontakesdark,lightorsystem, 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 indesign/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 owndesign/tokens.json, which has no light set, so it stays dark until it adds one. - An
llmskey forllms.txt. Withenabled, the site writesllms.txtat its base: an H1 with the name, the description, one H2 per collection with absolute links and descriptions, and## Optionalfor the collections listed inoptional. WithmarkdownPages, each page also has a Markdown copy at its address withindex.html.mdafter it, and the page links to it.sitekit initturns it on for a new site, and a site without the key does not change. It is a community proposal, not a search feature. Seedocs/llms.md. sitekit checkverifiesllms.txtwhen 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 withrole="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. TheCalloutcomponent 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 aftercallouts.ts,calloutIcons.ts,remarkCallouts.ts, the change inrenderMarkdown.tsand the callout styles ofprose.cssare copied from this version. Seedocs/callouts.md. sitekit upgrade, to bring a generated site up to the installed kit. For each file insite/.sitekit.jsonit 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-runprints 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 writesdocs/, 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 tositekit.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. Seedocs/upgrading.md.- Content findings in
sitekit checkand in the build. The markdown is read as data and each problem is reported asdocs/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, anorderthat is not a number, two headings that make the same anchor, and an unknown callout marker such as[!NOTES].checkcounts them and exits with 1 on anyerror, the build prints them and does not fail. A missing image and a badorderare errors, the rest warnings, and the newcheckkey insitekit.config.jsonsets each kind toerror,warningoroff; 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 thatloadSitecollected while rendering, and that nothing printed, are replaced by these findings. A site generated earlier gets the findings incheckat once, because the CLI reads them, and in the build once it copies the changed files oftemplate/src/andastro.config.tsfrom this version. Seedocs/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 asitekit.config.jsonexample 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 indocs/content.mdis replaced by links, because the reference already lists them. The documentation site keeps two example texts on itsanonymize.allowlist, since the checks page shows them. Seedocs/options.md.
Changed
- The project site announces
https://miguelcolmenares.com/docs-sitekit/as its address, in its canonical links, its sitemap and itsllms.txt. The personal domain serves the site through a proxy, and GitHub Pages keeps answering at the old address. A site generated withinitis not affected. - The default accent is the VS Code blue:
accent#4fc1ff,accent-strong#007accandaccent-contrast#ffffff, in place of the purple. A site generated withinittakes the blue from the kit it is generated with. A site generated earlier keeps its owndesign/tokens.json, so it stays purple until its owner changes that file. - The Action’s Marketplace icon is blue,
branding.colorinaction.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
Buttonwas 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 outlineButtonhad a shadow, against the rule of 1 px borders. The command of aCommandBoxscrolls 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 afterbutton.tsxandCommandBox.tsxare copied from this version. - The name of the tool is
docs-sitekiteverywhere 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. Thesitekitcommand 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<scriptbehind 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 copydescribe.tsfrom 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 topackage.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,listandadd.initreadspackage.jsonand the git remote, findsdocs/,docs/tutorials/,docs/examples/andexamples/, 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 insidedocs/. 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 workflowinitwrites 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.jsonon 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 a404.htmlthat is not a copy ofindex.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.
Last updated