Skip to content

Jig 0.6.0

Choose a tag to compare

@timessuman timessuman released this 11 Sep 04:03
· 357 commits to main since this release
79d3091

The token layer stops hiding in a dotfolder, and check starts reading it back.

Both came from the same question — who should write the tokens — and the answer depended on something that did not exist: nothing validated the token layer's own declarations. init checked a brand colour once, at write time, and no command ever looked again. A file edited afterwards, by a person or an agent, went unexamined: --color-text-weak dropped to 22% opacity and check reported "No findings".

Upgrading

npx jig-ui@latest update
npx jig-ui@latest init

Two commands this time: init is what writes the barrel and can relocate the token layer. Existing installs keep their .jig/tokens/ layout — nothing moves unless you move it, because relocating files could break an import you wrote yourself.

Added

  • check validates the token layer. Text roles to 4.5:1, interface strokes to 3:1, in both themes, plus --text-prose at 18px and --size-touch-target at 48px. Alpha foregrounds are composited over each surface first — Jig's foregrounds are alpha by design, so a ratio before compositing means nothing. Only floors, never density.

  • H-47 enforces the half of itself it only stated. Its correction always read "consume the semantic role, not the primitive"; the detector caught raw hex and raw px and nothing else. color: var(--brand-l) was silent — and it is the worse case, because it looks exactly like correct token usage while reading a bare number and bypassing every theme override.

  • exempt in jig.config.json, for surfaces that render outside the cascade: an OG card in an SVG foreignObject carries no stylesheet, a PDF renderer never sees CSS. Those files were in permanent violation, which is an adoption blocker — a check that cannot pass is a check people switch off.

    Nothing is exempt by default and no filename is baked in; this list is the only source. Every run reports the pattern and what it excused, because an over-broad glob does not fail — check simply gets quieter, and quieter looks like progress:

    5 file(s) exempt via jig.config.json and not scanned:
      src/*-card.css  (5 files — likely too broad, review it)
      src/nope.css  (matches nothing — check the path)
    

    Prefer an exact path. src/cv/pdf/** is a fact about a tree; **/*-card.tsx is a naming coincidence that would also excuse every real card component you have.

  • One import per surface, through a barrel. jig/theme.css imports the brand file and one mode file; your stylesheet imports that single line and never changes again. Switching mode rewrites Jig's file, not yours.

Changed

  • The token layer follows your project's layout. .jig/tokens/ was right everywhere by being right nowhere. The default is now a jig/ directory beside the stylesheet being wired — app/assets/stylesheets/jig/, src/styles/jig/, resources/css/jig/ — so the import is ./jig/theme.css rather than ../../../.jig/tokens/….
  • The mode is chosen before init runs. It is the most consequential thing init writes and the thing it is worst at choosing. The command file now tells the agent to ask what the product is, map each surface, write the config, then run. init also reports the surfaces it used rather than the ones it defaulted to.
  • A barrel holds exactly one mode, never a merge. Importing all three into one document leaves only the last — verified in a browser, it yields operator throughout.

Fixed

  • Tailwind v4 does not scan workspace packages — documented, with the @source directive it needs. Nothing errors when this bites: the class lands on the element, no rule exists to match it, and the style simply does not apply.
  • H-47's built-in token-layer skip was over-broad. It matched (brand|mode).*.css with the directory optional, so a project's own src/legacy/brand.colors.css was silently exempt from the primitive check wherever it sat. Scoped to the token layer's directory now.
  • The token audit follows the token layer instead of reading a fixed directory. It was written when .jig/tokens/ was the only possible answer, so moving the layer made it find nothing and report nothing — caught in a pre-release smoke test. A check that goes quiet when its subject moves is worse than one that was never written, because the silence reads as a pass.

Full changelog: https://github.com/timessuman/jig/blob/main/CHANGELOG.md