jig-ui 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,106 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.24.0 (2026-09-30)
4
+
5
+ The owner's word held to one rule, Jig's instructions in your project's AGENTS.md,
6
+ and Jig tested on Linux, macOS and Windows.
7
+
8
+ ### Added
9
+
10
+ - **`jig checksum <spec>`** prints a spec's checksum, the value its
11
+ `.checked.json` records. It had been left to agents to compute from the
12
+ procedure's description, and a hand-computed value was easily wrong.
13
+ - **`route:` is a spec field**, for a page whose surface name does not say where
14
+ it is served.
15
+ - **Your project's `AGENTS.md` carries Jig's instructions for your agent.**
16
+ `init`, `install` and `update` create the file if it is missing, or add Jig's
17
+ block to the one you have: load the skill before UI work, how the loop runs,
18
+ the owner's-word rule, and what each of Jig's files is for. With Claude Code,
19
+ a block in `CLAUDE.md` imports it, so every session loads it. Jig owns only
20
+ what is between its markers. `check` reports the block missing or edited,
21
+ `ship` is not ready without it, the Stop hook holds a session that removed it,
22
+ and `jig update` puts it back.
23
+
24
+ ### Changed
25
+
26
+ - **The owner's word is held to one rule, everywhere Jig records it.** A spec
27
+ confirmed, a drawing approved or skipped, a re-judge left for later, a tweak's
28
+ change and a decision's reason are each the owner's own words, and words that
29
+ say that thing: a remark about the layout is not a skip of the mockup, and a
30
+ yes to one question is not a yes to the spec. One check now covers all of
31
+ them. Three had no check before: `confirmed: true` needs the owner's yes to
32
+ being asked, a tweak's `change` must be words they said, and `decide`'s quoted
33
+ reasons must be too. The skill states the rule.
34
+ - **A field Jig does not read is refused where it would be written.** When the
35
+ procedure named no place for something, agents invented one: front-matter
36
+ keys, verdict ids, JSON fields that nothing reads, so what they said reached
37
+ no check. A spec key a session adds, a verdict-file field holding a list or an
38
+ object, and an unknown tweak.json field are now refused, each pointing at the
39
+ place that exists. Keys a spec already had are not held against it.
40
+ - **A spec is drafted where Jig reads it, and checked as itself.** It is written
41
+ at `.jig/specs/<name>.spec.md` from the first draft, and its shape is checked
42
+ before the owner is asked to confirm it. Asking to confirm a spec that is not
43
+ there is refused, and so is finishing a spec session without writing it. A
44
+ named spec is never checked in place of another page's.
45
+ - **A critique files one problem once.** A difference goes under `differences`
46
+ only when no rule or decision already holds it, so the counts `ship` reports
47
+ count problems, not entries.
48
+ - **The gate asks for the probe files it re-takes to be committed.** It renders
49
+ a changed page again as a session stops, after the last commit; like the
50
+ lock, it now stops once to have those files committed on their own.
51
+ - **`jig gate` run by hand reports and renders nothing.** Without a transcript
52
+ it cannot tell which pages are in play, and it had re-rendered every one.
53
+ - **`motion: none` can say why**, as in `none — this page adds no movement`.
54
+ - **A file a session never wrote is taken as it found it**, committed or not,
55
+ so a session is not answerable for a draft it found.
56
+
57
+ ### Fixed
58
+
59
+ - **Jig works the same on Linux, macOS and Windows, and is tested on all three.**
60
+ Every change now runs the full suite on each, on Node 22 and 24. The first run
61
+ found that rendering a page needed a WebSocket Node 20 does not have, so Jig
62
+ now needs Node 22 or later (Node 20 is end-of-life) and says so if it is run
63
+ on an older one; and that on Windows no browser was ever found to render with:
64
+ Edge, Chrome installed per user, and commands on PATH are now found.
65
+ - **A project checked out on Windows reads the same as anywhere else.** Git on
66
+ Windows gives files CRLF line endings. Jig parsed a spec with them as having
67
+ no regions at all, a spec's check no longer matched it, and every comparison
68
+ with a file's committed copy read as a change. Every text file Jig parses or
69
+ compares is now read with its line endings normalised.
70
+ - **Two Jig runs at once no longer fail on Windows.** Windows refuses to replace
71
+ a file another process has open, where Linux and macOS allow it; writing a
72
+ file Jig records (the install manifest among them) now retries briefly there,
73
+ and the manifest's lock treats a lock file Windows is still deleting as held
74
+ for a moment, not as an error.
75
+
76
+ - **The docs say what the code does.** The README said `check` reports a
77
+ pre-0.4.0 install's leftovers (only `init` does); the procedure named five
78
+ reasons `ship` owes a page (there are six, one a re-probe) and described the
79
+ spec checksum as leaving out one line where the code leaves out two. Tests
80
+ now fail when the procedure stops naming a state `ship` reports, a line the
81
+ checksum leaves out, or a command the CLI registers.
82
+ - **The README no longer counts the rules `check` decides by hand.** It named
83
+ "the seven mechanical rules" from 0.1.0; it now points at `rules.index.json`.
84
+ - **An `exempt` path works the way you write it.** `./src/card.tsx`,
85
+ `src\\card.tsx` and an absolute path inside the project all mean
86
+ `src/card.tsx`. A path outside the project was dropped without a word; it is
87
+ now named in the report with what to write instead, and a bare file name that
88
+ matches nothing is answered with where that file is.
89
+ - **A fact's `source` that holds a sentence** is told to put it in `note`.
90
+ - **The README says what Jig does.** It said `init` was the only command that
91
+ writes into your repo and that nothing of Jig's is kept in it (a project-scope
92
+ install writes the skill and rules into your repo's agent folder); pointed
93
+ agents at `AGENTS.md`, which users do not receive; counted 95 rules the CLI
94
+ cannot decide (it is 120), two critique readers (three) and four per-page
95
+ commands; described `check --ci` as errors only; said the token layer changes
96
+ nothing on the page, beside a `color-scheme` line that does; and claimed Jig
97
+ knows every page that changed, which it does not for a page rendered on
98
+ request. Its `exempt` example named one project's files as if they were a
99
+ pattern; it now explains how to choose your own: a file that renders outside
100
+ your stylesheets, or a page you will not revisit, since `check --all` and
101
+ `ship` read every file. The slash-command table
102
+ lists `verdicts`, `probe` and `checksum`.
103
+
3
104
  ## 0.23.0 (2026-09-29)
4
105
 
5
106
  Rules for the prose a page ships and for how it moves, a spec that says what
package/README.md CHANGED
@@ -2,10 +2,25 @@
2
2
 
3
3
  A design system written to be consumed by coding agents, not read by designers.
4
4
 
5
- Framework-agnostic. Tokens are CSS custom properties; rules are stated in CSS
6
- properties and behaviour, never in one framework's class names.
7
-
8
- Installed as `npx jig-ui` — the bare name was taken on npm.
5
+ **Jig is framework-agnostic.** It works with what you already build with:
6
+
7
+ - **Any framework.** React and Next.js, Vue and Nuxt, Svelte and SvelteKit,
8
+ Astro, Angular, Solid, Rails, Laravel, Django, Phoenix, ASP.NET, or plain
9
+ HTML. `check` reads each one's files as they are (see
10
+ [What `check` covers](#what-check-covers)).
11
+ - **Any way you style.** Plain CSS, SCSS or Less, CSS modules, Tailwind, or
12
+ CSS-in-JS.
13
+ - **Any content.** Pages built ahead of time or rendered from a backend.
14
+ - **Any coding agent.** Claude Code, Codex, Cursor, opencode, Gemini CLI, or any
15
+ other that reads a skill file.
16
+ - **Any operating system.** macOS, Linux and Windows.
17
+
18
+ Nothing in it belongs to one framework: the tokens are CSS custom properties,
19
+ and every rule is stated in CSS properties and behaviour, never in one
20
+ framework's class names.
21
+
22
+ Installed as `npx jig-ui` — the bare name was taken on npm. It needs Node 22 or
23
+ later.
9
24
 
10
25
  ## Two ways to use it
11
26
 
@@ -85,24 +100,43 @@ but never adds one.
85
100
 
86
101
  Every agent reads a `skills/jig/SKILL.md`, so adding a new harness is a config
87
102
  change rather than a new code path. Codex uses the cross-agent `.agents/`
88
- directory and additionally gets a short pointer block in `AGENTS.md` — that file
89
- is read into every session, so it names the skill rather than restating it.
103
+ directory.
90
104
 
91
- Install writes the skill file **and its rules** to one place only — beside the
92
- skill file itself. Nothing of Jig's is vendored into your repo; your agent reads
93
- the rules from the install. Installing at project scope when the same agent is
105
+ Install writes the skill file **and its rules** to one place only, beside the
106
+ skill file itself: in your repo's agent folder at project scope (the default),
107
+ in your home directory with `--scope global`. Your agent reads the rules from
108
+ there; nothing is copied into your source. At project scope it also keeps a
109
+ block in `AGENTS.md` (below). Installing at project scope when the same agent is
94
110
  already installed globally warns rather than creating a second, contradicting
95
111
  skill.
96
112
 
113
+ ### Your agent's instructions: `AGENTS.md` and `CLAUDE.md`
114
+
115
+ Most people run Jig through an agent, and `AGENTS.md` is the file agents read at
116
+ the start of every session. So Jig makes sure your project has one: `init`,
117
+ `install` and `update` create it if it is missing, or add Jig's block to the one
118
+ you have. The block is short: load the Jig skill before any UI work, how the
119
+ loop runs, the owner's-word rule, and what each of Jig's files is for.
120
+
121
+ With Claude Code, which reads `CLAUDE.md` instead, Jig also adds a block there
122
+ that imports `AGENTS.md` (`@AGENTS.md`), so every session loads it without the
123
+ agent having to choose to.
124
+
125
+ Jig owns only what sits between its markers, `<!-- jig:start -->` and
126
+ `<!-- jig:end -->`. Write your own instructions above or below the block; Jig
127
+ never reads or changes them. If the block goes missing or is edited, `check`
128
+ says so, `ship` is not ready until it is back, a session that removed it is held
129
+ by the Stop hook, and `jig update` puts it back.
130
+
97
131
  ## Set the project up
98
132
 
99
133
  ```bash
100
134
  npx jig-ui@latest init
101
135
  ```
102
136
 
103
- `init` is the only command that writes into your repo. It runs on a project
104
- with nothing in it and on one with years of CSS, and behaves differently in
105
- each — because the useful thing to do differs.
137
+ `init` sets the project up: the token layer, `jig.config.json`, one import in
138
+ your stylesheet, and Jig's block in `AGENTS.md` for your agent. It runs on a project with nothing in it and on one with years of
139
+ CSS, and behaves differently in each, because the useful thing to do differs.
106
140
 
107
141
  ### An existing site
108
142
 
@@ -157,15 +191,17 @@ set of cards with no list element — rather than a wall.
157
191
  #### When you do run `init`
158
192
 
159
193
  The token layer is a set of custom property declarations. Declarations nothing
160
- references change no pixel, so adding it does not restyle your site.
194
+ references change no pixel, so adding it does not restyle anything you have
195
+ styled. One line is the exception, below.
161
196
 
162
197
  - **Different names never collide.** Your tokens and Jig's sit side by side; each
163
198
  is used by whoever asks for it. You can adopt one token at a time, or none.
164
199
  - **If a name is the same in both, yours wins.** The import goes above your own
165
200
  rules, and the later declaration is the one that applies.
166
201
  - **One line does more than declare a token:** `color-scheme: light dark`, which
167
- tells the browser your page supports both, so scrollbars and form controls
168
- follow the reader's system setting.
202
+ tells the browser your page supports both. On a reader's dark system,
203
+ scrollbars, form controls and any background you have not set yourself turn
204
+ dark. If your site is light only, remove that line from the brand file.
169
205
 
170
206
  #### You decide how it is wired
171
207
 
@@ -233,8 +269,9 @@ are a list. That is the whole loop. Repeat it wherever it is worth repeating.
233
269
  The first `check --all` on a big repo is a long list, and the list is not a
234
270
  to-do. Read it in this order:
235
271
 
236
- 1. **`check --all --ci` first.** Mechanical bucket, errors only, exit code you
237
- can put in CI. It is the short list, and every line on it is decidable.
272
+ 1. **`check --all --ci` first.** The rules a machine decides, and nothing else,
273
+ with an exit code you can put in CI: it fails on any error. It is the short
274
+ list, and every line on it is decidable.
238
275
  2. **Then warnings, by rule rather than by file.** The report groups by rule id,
239
276
  and a rule firing forty times is one decision made once, not forty.
240
277
  3. **Then one page at a time.** `check` defaults to the files you changed, so
@@ -329,9 +366,6 @@ coherent monochrome UI and makes the missing decision visible instead of
329
366
  inventing a purple (`A-01`). Set `--brand-h/-s/-l` in the brand file when you
330
367
  have decided, or tell your agent to ask you.
331
368
 
332
- Add `--yes` to accept every derived default non-interactively — the mode CI and
333
- agents run in.
334
-
335
369
  ### Where the token layer goes
336
370
 
337
371
  Beside the stylesheet it wires, so it sits with the rest of your CSS rather than
@@ -370,11 +404,12 @@ overwrites a config or brand file you have edited.
370
404
 
371
405
  | Command | What it does |
372
406
  | --- | --- |
373
- | `install --agent <name> [--scope project\|global] [--hook]` | Puts the skill and its rules where your agent will find them. Writes nothing else into your repo, unless you ask for `--hook`. |
374
- | `init [--yes]` | Sets the project up: CSS system, brand colour, token files, `jig.config.json`, wired imports, baseline check. The only command that writes into your repo. |
407
+ | `install --agent <name> [--scope project\|global] [--hook]` | Puts the skill and its rules where your agent will find them. At project scope, also keeps Jig's block in `AGENTS.md` (and `CLAUDE.md` for Claude Code); with `--hook`, adds the Stop hook. |
408
+ | `init [--yes]` | Sets the project up: CSS system, brand colour, token files, `jig.config.json`, wired imports, baseline check. |
375
409
  | `check [--all] [--ci] [--json]` | Runs the rules a machine can decide. Reports findings by rule id. |
376
410
  | `update` | Refreshes an install to a newer version, leaving alone any file you have edited. |
377
411
  | `seo [--json]` | Audits what a search engine and a link preview read, across the whole project: a route whose metadata says `noindex` sitting in the sitemap, two pages claiming one title, a sitemap that lists nothing or lists paths a crawler drops. Whether a sitemap and a robots file exist is counted, not reported: no rule asks for either, and a site with no domain yet cannot write an honest sitemap. Needs no config, no decisions and no spec. |
412
+ | `checksum <spec>` | Prints a spec's checksum, the value its `.checked.json` records as `spec`, so the spec's reader never computes it by hand. |
378
413
  | `verdicts <surface>` | Verifies a critique's verdict files and computes its counts: every rule in each pass judged once, no id that does not exist, no rule in the wrong arm, and no verdict the render probe contradicts. |
379
414
  | `probe` | Prints the render probe — one expression the critique runs in a browser at each width. It operates the menu, measures sideways scroll, and reads whether the styles and tokens applied. |
380
415
  | `ship` | Says whether the project is ready to ship, by everything Jig checks: `check --all --ci` and `seo` with no errors, and every confirmed page critiqued as it stands, with no finding you have not ruled on. Exits non-zero until it is, and names what Jig does not check. |
@@ -417,12 +452,17 @@ on the result — the CLI reports, the agent applies the judgment half.
417
452
  | `/jig spec invoice page` | No CLI. What exactly is being built — a page, feature or functionality — at its smallest useful version, at every screen size |
418
453
  | `/jig mockup` | No CLI. Low-fidelity design of that spec, reviewed before code — in HTML, Figma or Google Stitch, whichever you choose |
419
454
  | `/jig make` | No CLI. High-fidelity: builds the actual page or feature from the spec and mockup |
420
- | `/jig critique` | `jig verdicts` + `jig probe`. Scrutinises what was built against the rules, its spec and its mockup: two reader arms write their verdicts to files, the CLI decides whether the review is complete, and a browser probe checks the verdicts against what the page actually does |
455
+ | `/jig critique` | `jig verdicts` + `jig probe`. Scrutinises what was built against the rules, its spec and its mockup: three readers that cannot see each other (one looks at the rendered page, one reads the source, one holds it to your decisions) write their verdicts to files, the CLI decides whether the review is complete, and a browser probe checks the verdicts against what the page actually does |
421
456
  | `/jig tweak` | No CLI. A small change to a built page that its approved mockup does not show: decided if it is a decision, specced, built, and re-judged where it could matter |
422
457
  | `/jig ship` | `jig ship` — then critiques every page that owes one, puts the findings to you, and runs again until the project is ready |
458
+ | `/jig verdicts <page>` | `jig verdicts <page>` — reports whether a critique is complete, unchanged |
459
+ | `/jig probe` | `jig probe` — the render probe a critique runs in a browser |
460
+ | `/jig checksum <spec>` | `jig checksum <spec>` — the value a spec's check records |
423
461
 
424
- `decide` runs once. The other four run for each page, feature or functionality, one
425
- at a time — never the whole product at once.
462
+ `decide` runs once. `spec`, `mockup` (or skipping it), `make` and `critique` run for
463
+ each page, feature or functionality, one at a time, never the whole product at
464
+ once; `tweak` handles a small change to a built page, and `ship` checks the whole
465
+ project before you release.
426
466
 
427
467
  Where each lands:
428
468
 
@@ -579,7 +619,10 @@ critiquing any page whenever you like, and `ship` judges every one.
579
619
 
580
620
  Waiting is tracked, not forgotten. The verdict lock records the page each
581
621
  critique judged, so Jig knows every page that changed since, every tweak that
582
- left its re-judge for later, and every page never judged. `/jig ship` is where
622
+ left its re-judge for later, and every page never judged. It knows a page by its
623
+ built file: a page rendered only on request is not tracked this way yet, and a
624
+ built page whose content comes from a backend reads as changed when that content
625
+ does. `/jig ship` is where
583
626
  none of it is optional: `jig ship` runs `check --all --ci` and `seo`, and names
584
627
  each page that owes a critique; the agent critiques each one in full, with
585
628
  readers that have not seen the conversation, and puts the findings to you. Each
@@ -668,8 +711,8 @@ In CI:
668
711
  code — nothing model-dependent, no network. As a pre-commit hook, plain `check`
669
712
  looks at changed files only.
670
713
 
671
- What you will not get from the CLI alone is the other 95 rules. `check` says so
672
- rather than letting a narrow pass read as a broad one.
714
+ What you will not get from the CLI alone is the 120 judgment rules. `check` says
715
+ so rather than letting a narrow pass read as a broad one.
673
716
 
674
717
  ## What `check` covers
675
718
 
@@ -690,10 +733,11 @@ character positions preserved, so a finding's line points at the real line in
690
733
  your `.vue` or `.tsx` file. Application code outside a style region is never read
691
734
  as CSS.
692
735
 
693
- The seven mechanical rules: hard-coded values past the token layer (`H-47`),
694
- contrast below the floor (`C-19`), removed focus rings (`E-29`), gradient text
695
- (`A-02`), backdrop blur (`A-04`), pure black and white (`C-18`), and the
696
- violet-band hue check (`A-01`, which asks rather than fails).
736
+ Which rules it decides: every rule in `rules.index.json` that names a
737
+ `detector`, among them hard-coded values past the token layer (`H-47`), contrast
738
+ below the floor (`C-19`) and removed focus rings (`E-29`). A `hybrid` one warns
739
+ and asks rather than fails (the violet-band hue check, `A-01`). `jig explain
740
+ <id>` prints any rule with who checks it.
697
741
 
698
742
  **It also reads the token layer itself.** The token layer is not application
699
743
  code, so no detector scans it — but it is where a mistake costs most, since every
@@ -736,10 +780,10 @@ npx jig-ui@latest update
736
780
  ```
737
781
 
738
782
  Files you have edited are left alone. Upgrading from a pre-0.4.0 install that
739
- vendored rules into your project's `.jig/`? `init` and `check` detect the
740
- leftover files, report them, and — with your consent, and never for a file you
741
- have edited — offer to remove just the install artifacts, keeping your tokens
742
- and config untouched.
783
+ vendored rules into your project's `.jig/`? `init` detects the leftover files,
784
+ reports them, and — with your consent, and never for a file you have edited —
785
+ offers to remove just the install artifacts, keeping your tokens and config
786
+ untouched. (`update`, finding no install, names them and points you to `init`.)
743
787
 
744
788
  Cursor's skill moved from `.cursor/rules/jig.mdc` to
745
789
  `.cursor/skills/jig/SKILL.md`; `init` finds the old file and offers the same
@@ -760,12 +804,15 @@ treatment.
760
804
  | `<css dir>/jig/mode.*.css` | Density, scale, rhythm, motion |
761
805
  | `<css dir>/jig/theme.css` | The barrel — brand + mode. This is what you import. With more than one mode, `theme.<mode>.css`, one per mode, each imported by its routes' layout. |
762
806
  | `.jig/state.json` | What `init` wrote, with checksums. `update` reads it to leave your edits alone. |
807
+ | `AGENTS.md`, `CLAUDE.md` | Your agent's instructions. Jig keeps one marked block in each (`CLAUDE.md` only with Claude Code); the rest is yours. |
763
808
  | `.jig/specs/`, `.jig/mockups/`, `.jig/critique/` | The design loop's record: what was agreed, what was drawn, what the review found. |
764
809
 
765
- `rules/*` and `rules.index.json` live beside your installed skill file, not
766
- in the project — see above.
810
+ `rules/*` and `rules.index.json` live beside your installed skill file: in
811
+ your repo's agent folder at project scope, in your home directory at global
812
+ scope. See Install, above.
767
813
 
768
- Which of these an agent loads, and when, is `AGENTS.md`.
814
+ Which of these an agent loads, and when, is the skill file's to say: `SKILL.md`,
815
+ beside the rules.
769
816
 
770
817
  ## Per-project declaration
771
818
 
@@ -787,20 +834,19 @@ Drop this in the project root so mode selection does not require asking on every
787
834
  { "match": "/admin/**", "mode": "operator" }
788
835
  ],
789
836
 
790
- // Files that render OUTSIDE the cascade, where a literal is the only thing
791
- // that works: an OG card serialised into an SVG `foreignObject` carries no
792
- // stylesheet, and a PDF drawn by a React renderer never sees CSS.
793
- //
794
- // Prefer an exact path. An exemption is a claim about ONE file's rendering
795
- // context, and that is usually literally true of one file. Reach for a glob
796
- // only where the directory exists to hold them — `src/cv/pdf/**` is a fact
797
- // about that tree; `**/*-card.tsx` is a naming coincidence that would also
798
- // excuse every real card component you have.
837
+ // Files `check` should skip. Empty unless you add to it; Jig never does.
838
+ // Add:
839
+ // - a file that renders outside your stylesheets (a generated social
840
+ // card, a PDF or email template), where literal values are the only
841
+ // thing that works;
842
+ // - an old page you will not revisit. Plain `check` reads only the files
843
+ // you change, but `check --all` and `ship` read every file.
799
844
  //
800
- // `check` names the pattern and its match count on every run, and says so
801
- // when one is excusing enough files to look like a mistake. Nothing is ever
802
- // exempt by default: this list is the only source.
803
- "exempt": ["src/components/og-card.tsx", "src/cv/pdf/**"],
845
+ // Write each path from the project folder (where this file is), the way
846
+ // your editor shows it: "src/social-card.tsx". A whole folder:
847
+ // "src/emails/**". `check` lists every entry and how many files it
848
+ // matched on every run, and tells you when one matches nothing.
849
+ "exempt": ["src/social-card.tsx", "src/emails/**"],
804
850
 
805
851
  // When pages are critiqued. Leave it out to decide each time; "at-ship"
806
852
  // says once that critiques and a tweak's re-judge wait for `/jig ship`,