Repository navigation
Releases: fwdslsh/unify
Release list
v0.11.14
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.14 changes
Fixed
- A generator's warnings reach the build log. unify passed a
--generatescript's stdout through but kept its stderr unless the script failed, soconsole.warn("skipped …")from a generator that exited 0 never appeared anywhere — fwdslsh.dev's generator skipped an unreachable article source for a whole deploy without a word in CI. A successful generator's stderr is now passed through as its stdout is; a failing one is still reported as P29 with its own message (§33.2, GEN-03).
v0.11.13
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.13 changes
Changed
unify-docs-template0.4.0: syntax colours and a copy button on every fenced code block. fwdslsh.dev had
both, from a script of its own; the docs sites built on the template showed plain code. The template now ships
assets/code.js, which its layout loads: it wraps each<pre><code>in a page's content with a copy button and
colours it with the vendored speed-highlight (CC0, under
assets/vendor/), the same library fwdslsh.dev used. The colours are newtheme.cssproperties,--syn-cmnt,
--syn-str,--syn-kwd,--syn-num,--syn-classand--syn-func. A page reads the same without the script,
and a hand-written<pre>without<code>(a.term-bodytranscript) is left as written.
v0.11.12
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.12 changes
Changed
unify-docs-template0.3.0: one theme for every fwdslsh.dev site. fwdslsh.dev, unify.fwdslsh.dev and
akm.fwdslsh.dev now share the docs template's stylesheet. The template's look takes the parts of each that
hold up best. From fwdslsh.dev: green-neutral surfaces in one hue, a 17px body, monospace section headings
opened by the/motif, Protest Revolution page titles, underlined links, a focus ring on every focusable
element, 44px targets and the faint page grid. From the docs sites: the blue secondary accent (--accent-2)
for inline code and badges, the gradient wordmark tile and the buttons.theme.cssnow lists every property
the stylesheet reads, grouped into palette, type, layout and shape. The new ones include--border-strong,
--accent-2,--focus,--glow,--grid-lines,--h1-font,--heading-font,--text-size,--leading,
--site,--gutter,--measure-wide,--sidebar, the radius scale and--dur. Prose keeps a 42rem measure
and code and tables get 52rem. The masthead is sticky at every width, except above a phone's docs-page
shortcut row.- Inline code stays whole. A token such as
--search-corpusmoves to the next line instead of splitting
at its hyphen, and in a table cell it never wraps; only a token longer than a whole line still breaks.
Previously,overflow-wrap: anywherelet a table squeeze a column until tokens broke mid-word on phones. - Renamed in the template:
.skipis.skip-link,.btn-ghostis.btn-secondary, and the wordmark tile's
slash is an SVG, so it renders before any font loads.body.widenow keeps the site's width and gutter;
body.homeremains the full-bleed front page. - The built-in templates' READMEs describe slotted includes instead of forbidding content between
<include>
tags (unify-default-template,-basic-,-blog-and-portfolio-0.1.3), and theextends:example names
unify-docs-template@0.3.0.
v0.11.11
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.11 changes
Changed
unify auditno longer compares a page that only redirects. A page whose first<meta http-equiv="refresh">
is immediate (content="0; url=…") sends its reader on before the page is seen: it is a stub that keeps an old
address working.page-orphan,title-duplicate,description-duplicateandtext-duplicatenow skip it, and the
duplicate grouping leaves it out, so a stub never makes the page it redirects to a duplicate of it. A site that
kept a stub at every moved address (akm.fwdslsh.dev, with 97 such pages) no longer reports a finding for each. A
delayed refresh is an ordinary page and is compared as one; every other finding,redirect-loopincluded, still
applies to a redirecting page (spec §24.4, rule AUD-18).
v0.11.10
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.10 changes
Changed
- A repeated heading's id follows GitHub:
setup,setup-1,setup-2. A Markdown heading that repeats
within a page took-2first, so every anchor written against a document's GitHub view (#setup-1) missed
the published heading and failed the reference check; documentation sites renamed their repeated headings to
dodge it. A repeat now takes the first-Nfrom 1 that no earlier heading on the page produced, GitHub's
slugger exactly. A site whose links already name-2for a second heading needs them changed to-1
(spec §10.4, rule MD-16). - The docs template is the fwdslsh documentation look, built to be extended.
templates/docs
(unify-docs-template0.2.0) is now the design unify.fwdslsh.dev uses — masthead, sticky sidebar, footer,
the dark palette with a green accent asassets/theme.csscustom properties (--accentand kin), and
landing-page components (.hero,.card-grid,.term,.btn) — with everything that names the site in
four includes:_includes/head.html,nav.html,docnav.htmlandfooter.html. A site that builds on it
withextends:writes those four files and its pages, and nothing else. It ships
scripts/import-docs.mjs, a library a generator calls to publish a repository'sdocs/folder at every
build (each document todocs/<its path>, a missing title or description filled in, a link leaving the
folder sent to GitHub). The All-pages directory groups a tree underdocs/by its own folders. The fonts
are opt-in (system fonts untilhead.htmlloads them), so a scaffold asks nothing of a third party. A site
scaffolded from an earlier docs template keeps its owntheme.css, whose old properties no longer apply;
unify updatelists the new stylesheet and includes before writing them. - A template may use as many includes, slots and opted-out pages as its design needs. Spec §19.1 required
every template to exercise each primitive exactly once; that constraint is gone (rule SCF-01 now asks only
for the layout and_includes/). - unify's documentation site extends the docs template, read in place from the repository, and publishes
docs/through the importer; each document indocs/carries its owndescription:frontmatter. The two
guides underdocs/guides/are now published too, where links to them used to go to a broken GitHub path.
v0.11.9
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.9 changes
Fixed
- A link to a Markdown page by its source path builds.
[the guide](guide/start.md)is the link that works
in an editor and a repository browser, and it failed the build as an unresolvable reference because only the
publishedguide/start.htmlexists. A link inhref,src,srcset,poster, a URL-valued meta or a refresh
URL whose path ends.mdand names an emitted Markdown page now has.htmlswapped in, keeping the rest of its
spelling (relative stays relative, query and fragment survive);--pretty-urlsand--base-urlthen treat it
like any link written.html, so it ships as/guide/start/. A.mdlink naming anything else — a typo, a page
held back by an underscore or--exclude, or an.htmlpage of the same name — is untouched and still fails the
reference check. This is what a repository whose docs already link themselves with.mdneeds to publish them
withextends:(spec §11.1b, rule URL-16).
v0.11.8
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.8 changes
Added
extends: build on a template without copying it (#118).
extends: <source>inunify.yaml, or--extends <source>, names a template — any formunify inittakes:
a built-in, a directory, a git repository, an npm package — thatbuild,audit,devandwatchread as
the lowest layer of the site. Its source tree's layouts and includes resolve where the site has none, and its
pages and assets publish where the site has nothing at the same path or output path: the site's own file
always wins, soindex.mdreplaces the template'sindex.htmlandassets/theme.cssreplaces its theme.
Only the template'ssite/(orsrc/) is read — never itsunify.yaml, generator or README, and nothing in
it runs. A pinned source (name@1.2.3,#<commit>, a built-in) is fetched once into
~/.cache/unify/templates/($XDG_CACHE_HOME,%LOCALAPPDATA%on Windows) and built offline after that; an
unpinned one is fetched once per run; a directory is read in place. An unreachable source exits 2 and writes
nothing.--dry-run, diagnostics andunify auditmark what came from the template. A repository whose
documentation isdocs/**can now publish it with a published template and oneunify.yaml, with no
vendored files and no fetch script.template:is unchanged: it is still the recordunify updatefetches,
and no build reads it (spec §34, rules EXT-01 to EXT-07; product-spec §6.1 names the fetch as the one network
access a build makes).- The five template packages are
0.1.2: theirunify.yamllists the new key, commented out.
Changed
- A template is found on npm by keyword, not by name. A template published to npm carries
unify-templatein itskeywords, as the five built-ins do, and that keyword is what npm searches and the
template list on fwdslsh.dev match. Theunify-<name>-templatenaming convention is no longer documented;
unify inittakes any package name as before (spec §19.9).
v0.11.7
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.7 changes
Changed
- Every built-in template is an npm package.
templates/<name>/carries apackage.jsonnaming it
unify-<name>-template—unify-default-template,unify-basic-template,unify-blog-template,
unify-docs-template,unify-portfolio-template— and.github/workflows/publish-templates.ymlpublishes
each whose version is not on npm yet, after packing it and scaffolding a site from the tarball with
unify init <dir> --audit.unify init unify-blog-template(or@<version>) now scaffolds the same
project asunify init blog;package.jsonis never scaffolded (§19.9), so nothing changes in a site. - The scaffold's guidance file is
README.md. The file every template placed at the project root as
AGENTS.mdis nowREADME.md— the same content, under the name npm shows as a package's page and a
repository shows first — sounify initwritesREADME.md,DEPLOY.mdandunify.yamlbesidesite/,
and keeps aREADME.mdthat already exists there as it is — the one file an existing copy of does not refuse
the scaffold, since a project usually has a README before it has a site (spec §19.4, product-spec §6.7, rule
SCF-09).
v0.11.6
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.6 changes
Changed
- Any npm package can be a template.
unify init <name>reads a bare word that is neither a built-in
nor an existing directory as an npm package (nameor@scope/name, optionally@versionor@tag), and
fetches it with your ownnpm pack. Naming a templateunify-<name>-templateis the convention that makes
it easy to find on npm, not a rule the CLI enforces;--auditis what tells a template from a package that
is not one. The cost is that a misspelled directory name reaches npm and fails there, with npm's message
(spec §19.9, rule SCF-13). The order of the forms is now built-in, git, directory, npm. keep: the filesunify updatenever overwrites.keep:undertemplate:inunify.yaml(a list of paths
relative to the file, besidesource:, the record) or--keep <path>(repeatable, relative to the working
directory, replacing the list) names the files this site customized.template:is now the one key that takes a
block:template: <source>alone is still the record, and the block spellssource:andkeep:under it. A listed file that exists is never overwritten — printed askeep <path>when the template's
copy differs, counted as kept in the summary, never asked about — and one that does not exist yet is added.
Nothing else reads the list and nothing is required of a template (spec §18 and §19.10, rules CFG-01, CFG-09
and UPD-04).- The look is a file the site keeps. Every built-in template's
assets/style.cssopens with@layer base, theme;
and@import url("theme.css") layer(theme);, expresses its look as custom properties in the base layer, and ships
assets/theme.csswith those properties at their defaults — yours to edit: a changed value changes the look, a
deleted one keeps the default. Every built-in now ships aunify.yamlwhosetemplate:block keeps that file and
unify.yamlitself, so neither the theme nor a line you uncomment is ever overwritten byunify update
(spec §19.11, rule SCF-16,docs/templates.md§3).
v0.11.5
Install
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bashOr download a binary below, chmod +x it, and put it on your PATH.
npm: npm install -g @fwdslsh/unify — Bun: bun add -g @fwdslsh/unify
| Platform | Download |
|---|---|
unify-linux-x86_64 |
download |
unify-linux-arm64 |
download |
unify-darwin-x86_64 |
download |
unify-darwin-arm64 |
download |
What v0.11.5 changes
The template record is one line in unify.yaml, and unify update is a copy you confirm; unify.template.json is gone.
Changed
- The record
initleaves istemplate: <source>inunify.yaml— the source as you typed it
(blog,unify-shop-template,https://…/templates/shop#v2,../shop). Nothing else is recorded: no
version, no file list, no hashes.--template <source>is the positional as an option. unify updatefetches the template again and copies its changed files over the project (spec §19.10).
It lists every file it would overwrite and add, asksoverwrite N file(s)? [y/N]when at least one file
would be overwritten, and writes nothing on any answer buty(exit 1).--yes/-yanswers for a
script;--dry-runlists and never asks. Nothing is removed, nothing outside the template's paths is
visited, and nothing merges.unify update <source>moves the project to another source and the line
follows.- The blog template's generator reads unify's source inventory (
generator-context.json's
inputs.sourcePages, §33.7) instead of parsing frontmatter itself, writes only the listing, and leaves the
feed to unify: with--base-urlthe posts'schema: BlogPostingactivatesfeed.xml(§29), so the script
writes no RSS and the scaffold links no feed it does not have yet (DEPLOY.md says where to add the link). - The scaffolds' AGENTS.md and DEPLOY.md name
unify build --audit --strictas the one-command release gate
and point at/_unify/preview/and the dev chrome. - Examples brought up to date: htmx 2.0.11 vendored in
htmx-fragmentsandeleventy-htmx;eleventy-htmx
pins@fwdslsh/unify ^0.11.4and itsnpm run buildis the full gate;forge-sveltemoves to Svelte 5.57.1,
gets aunify.yaml, generates its course-notes index throughgenerate:from the source inventory instead of
a hand-run script writing intosite/, and now audits clean;seed-librarybuilds its seasonal-notes index
from the inventory too, byte-identical to before.
Removed
unify.template.json(the record and the manifest),unify update --adopt, and the per-file
conflict logic. A project that still has the 0.11.2 file is told the exacttemplate:line to add.
Added
- A template-authoring convention, and the built-in templates follow it (
docs/templates.md§3, spec §19.11):
tooling ships in place and everything a site fills in ships only as examples undersite/_examples/, which the
default_*exclusion keeps out of the build — copy one into place, edit the copy, andunify updatenever lists
it. The five built-ins now shipindex.html,404.html, the layout, the nav, the stylesheet androbots.txtin
place (plus the docs template's "All pages" starter and the blog's generator), and their pages, posts, guide pages,
project pages and the blog's authors file as examples. Onlydocs(catalog: true) andblog
(generate: scripts/gen.mjs) ship aunify.yaml;initwrites the all-commented file for the others, and it is
then the site's. The blog generator writes an empty listing and feed for a scaffold with no posts yet.