SLASHED has one version number. It must be identical in every artifact. If you touch anything version-related, you are responsible for keeping all of these in sync:
| File | Field | How it's kept correct |
|---|---|---|
package.json |
.version ← source of truth |
you bump it (npm version) |
package-lock.json |
.version + .packages[""].version |
npm version; checked by check:version (CI) |
docs/roadmap.md |
Current version: **X.Y.Z** line |
version-sync; checked by check:version (CI) |
docs/llm-guide.md |
Version: **X.Y.Z** header line |
version-sync; checked by check:version (CI) |
configurator/package.json |
.version |
version-sync; checked by check:version (CI) |
configurator/package-lock.json |
.version + .packages[""].version |
version-sync; checked by check:version (CI) |
dist/*.css (unminified) |
/*! SLASHED vX.Y.Z */ comment header |
build-derived — stamped from package.json/tag by bundle.js; dist/*.css is git-ignored, so it cannot drift. release.yml re-verifies the stamp before publishing |
| Configurator UI version pill | baked in via Vite __SLASHED_VERSION__ at build time |
build-derived — injected from root package.json at Vite build; cannot drift |
The first six rows are the ones you ever sync; the last two are build-derived
(regenerated from package.json at build time and not committed as text you edit),
so version-sync/check:version intentionally don't touch them — never hand-edit them.
Never edit version numbers by hand. Use npm version then the sync script:
npm version <new-version> --no-git-tag-version # bump the source of truth
npm run version-sync # propagates to all files above
npm run check:version # must pass — CI fails if it doesn't
npm run build # rebuilds dist/ with stamped headersIf you are not bumping the version but you touch any of the files in the table
above, still run npm run check:version before committing to confirm nothing
has drifted.
The configurator/ package is private and internal. Its version must always
equal the root framework version. npm run version-sync handles this
automatically — but if you ever edit configurator/package.json directly
for any reason, immediately re-run npm run version-sync and
npm run check:version.
The version shown in the configurator UI (v{frameworkVersion}) is injected
at Vite build time from the root package.json via __SLASHED_VERSION__
(see configurator/vite.config.js). It does NOT come from
configurator/package.json at runtime. This means: a correct UI version
requires a rebuild+redeploy, not just a file edit.
| Command | What it does |
|---|---|
npm run build |
Build all CSS bundles + docs + sync configurator API |
npm run version-sync |
Sync all version references to root package.json |
npm run check:version |
Verify all version references match (CI gate — run before every commit that touches versions) |
npm run check:llm-guide |
Verify docs/llm-guide.md only references live tokens and its header token count matches the live total (CI gate) |
npm run check:doc-refs |
Verify every hand-written doc only references live --sf-* tokens / .sf-* classes (or names allowlisted in docs/ref-allowlist.json) (CI gate) |
npm run check:release-add |
Verify the release workflow's git add stages every file version-sync writes (CI gate) |
npm run check:layer-order |
Verify docs/architecture.md's @layer block and specificity ladder match core/layers.css (CI gate) |
npm run check:macros |
Verify .sf-* macro classes match docs/macros.md (CI gate) |
npm run check:registry |
Verify token-registry.json is in sync with source (CI gate) |
npm run audit:check |
Verify docs/registry.json matches source without writing (CI gate) |
npm run lint:css |
Lint all CSS source with stylelint (CI gate) |
npm run lint:css:fix |
Lint CSS source and auto-fix violations |
npm run docs |
Regenerate docs and sync configurator API index |
npm run docs:tokens |
Regenerate docs/tokens.md only |
npm run docs:index |
Regenerate docs/token-index.md + .json only |
npm run docs:api |
Regenerate docs/api-index.md + .json only |
npm run docs:classes |
Regenerate docs/classes.md only |
npm run gen:registry |
Regenerate token-registry.json (stable id assignments) |
npm run configurator:sync |
Push docs/api-index.json → configurator/src/data/api-index.generated.json |
npm run audit |
Audit CSS tokens for consistency, writing docs/registry.json |
npm run watch |
Rebuild CSS bundles on file change (dev watch mode) |
npm run test:unit |
Run the Node --test unit suite only, without the Playwright e2e build. Some tests read from dist/ — run npm run build first on a clean checkout (CI instead downloads the dist artifact from the build job before this step) |
npm test |
Full suite: build → unit → Playwright e2e |
Releases are handled by release-it (.release-it.json). The hooks run
version-sync and build automatically after bumping.
npm run release # patch bump (default)
npm run release:minor # minor bump
npm run release:major # major bumpAfter the tag is pushed, GitHub Actions (release.yml) does the rest:
- Builds and publishes the GitHub Release with dist bundles
- Syncs all version artifacts to
main - Dispatches
deploy-configurator.ymlto redeploy the configurator app - Dispatches
publish-dist.ymlto update the dist branch
Do not manually trigger partial steps of this pipeline — run the full
npm run release so nothing ends up out of sync.
- Source lives in
core/(required) andoptional/(opt-in). scripts/bundle.jsconcatenates and buildsdist/.- Every unminified dist bundle is stamped with a minifier-safe
/*! SLASHED vX.Y.Z ... */header (bang-comment, per MIT's copyright-notice requirement — see LICENSE). - The stamp version must match
package.json—release.ymlverifies this before publishing the GitHub Release.
docs/llm-guide.md is the authoritative LLM reference for the framework API.
It must stay in sync with the live token set. The CI gate check:llm-guide
enforces this mechanically — but the gate only catches renamed or deleted
tokens. You are responsible for the qualitative layer:
Any PR that touches core/*.css, optional/*.css, or token-registry.json
must also review docs/llm-guide.md and update it if needed.
Changes that always require a guide update:
- New PUBLIC or PUBLIC-ADVANCED token added → add it to the relevant section
- Token renamed or deleted → the CI gate will catch stale refs; fix them
- New token role, tier, or behaviour documented in a token's description
Changes that may require a guide update:
- Default value changed for a widely-used knob
- New layout primitive or macro added
- New browser support floor or feature gating change
After any token-touching PR, verify with:
npm run check:llm-guide # must pass — CI fails if it doesn't
npm run check:doc-refs # must pass — no hand-written doc may reference a dead token/classcheck:doc-refs extends the same live-reference guarantee to every
hand-written doc (architecture, components, theming, macros, states, motion,
layout, user-manual, README, CONTRIBUTING), not just the LLM guide. When you
rename or remove a token/class, either update the referencing docs or — if a
mention is deliberately non-live (a removed name in an example, an illustrative
instance token, an example of a component the framework does not ship) — record
it in docs/ref-allowlist.json with a reason. docs/migration.md (historical)
and docs/roadmap.md (forward-looking) are whole-doc exclusions.
npm test # full suite (requires built dist — runs build automatically via pretest)
npm run test:install # install Playwright browsers (first time only)Do not skip the pretest build step. Tests import from dist/ and will fail
with stale bundles.