jig-ui 0.13.0 → 0.14.1

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,93 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.1
4
+
5
+ `jig seo` cites only what a rule says.
6
+
7
+ ### Fixed
8
+
9
+ - **No finding for a missing sitemap or robots file.** Both were filed under
10
+ rules that do not ask for them: `J-123` is about a page that must not be
11
+ indexed and says `robots.txt` is not it, and `J-124` is about a sitemap that
12
+ contradicts the pages. A project with no domain yet cannot write an honest
13
+ sitemap, so the only way to clear the old finding was to invent one. Both are
14
+ now counts on the `JIG_SEO` line.
15
+ - **A sitemap of paths is a `J-124` error.** A `<loc>` that is `/about` rather
16
+ than a full URL was read as a route, although a crawler drops it. `J-124` now
17
+ names that case and says no sitemap is the honest one until there is an
18
+ origin.
19
+ - **`pages=` counts pages.** It counted any file that mentioned `<title>` or
20
+ `<meta>`, so a build script, a test, a data module and a layout were pages and
21
+ a home page inheriting its layout was not. A page is now a route a framework
22
+ serves, or a whole-document template outside the layout and partial folders.
23
+ A dynamic route counts once.
24
+ - **Framework routes match their sitemap entries.** `src/pages/admin` was read
25
+ as `/pages/admin`, so a `noindex` Astro or Next page listed in the sitemap
26
+ went unreported.
27
+
28
+ ## 0.14.0
29
+
30
+ What a stranger meets before the page, what the page must not hand them, and a
31
+ project that states its own direction.
32
+
33
+ ### Added
34
+
35
+ - **`J-120` to `J-127`, search and sharing.** A page a stranger reaches through
36
+ a search result or a pasted link is judged on what that reader meets first: a
37
+ title that names this page and not the site, a description that says what the
38
+ page holds, a canonical URL where more than one address serves the same
39
+ content, and a share image where a link is meant to be shared. A page that
40
+ must not be indexed says so in the page, not only in `robots.txt` — an
41
+ operator surface is the case the rules were written around.
42
+ - **`jig seo`.** A project-level audit the page rules cannot do from one file:
43
+ a `noindex` route listed in the sitemap, two pages claiming the same title, a
44
+ site with no sitemap or no `robots.txt`, a sitemap with nothing in it. It
45
+ reads metadata wherever the framework puts it, and it does not require
46
+ `DECISIONS.md` — a project without one still gets the audit.
47
+ - **`K-128` to `K-134`, safety at the interface.** This is not a security
48
+ review, and nothing here should be read as one. It is the set of interface
49
+ decisions that are also safety decisions: markup built from text a reader
50
+ supplied, a link opened into a new context, a form that submits across
51
+ origins, a credential or a token rendered into the page, an error that quotes
52
+ the system back at the reader. There is no `jig secure` command, because a
53
+ command implies a guarantee this cannot make.
54
+ - **`L-01` Step 6, how the layout collapses.** A composition is not finished
55
+ until you have said what happens to it at each width where the content needs
56
+ it: reduce the count, never the size; order survives; distinction survives;
57
+ type comes from the fluid scale, not from a breakpoint; content wider than
58
+ the screen scrolls inside itself rather than pushing the page sideways.
59
+ - **A fourth judged width: 1600.** Three widths never asked what an unbounded
60
+ layout does with room it was never given. A measure that keeps growing, a
61
+ row that keeps stretching and a page that turns into a gutter with a line of
62
+ text in it only show themselves past the desktop width. `jig probe` renders
63
+ 360, 768, 1280 and 1600, and `spec` composes for all four.
64
+ - **The project's own decisions are judged, one verdict each.** `DECISIONS.md`
65
+ is the file the agent is most likely to read once and then drift from, so
66
+ `jig verdicts` now carries a `decisions=` arm: every decision in the file is
67
+ judged against the page, and an unjudged decision is a failure like any other.
68
+
69
+ ### Changed
70
+
71
+ - **`/jig decide` asks for the north star and the personality.** The north star
72
+ is the product's, not a page's — what someone can do that they could not
73
+ before, and what the product gives up to do it. A page's own purpose stays
74
+ `spec`'s question and inherits its direction from here. Personality is asked
75
+ through the four things that produce it, each named with the token it
76
+ becomes: type, colour, corners, language. An owner with no gut feeling is
77
+ asked what the reader already uses — and pointed away from direct
78
+ competitors, because a project that borrows from one looks like a
79
+ second-rate version of it.
80
+ - **Every question in `decide` and `spec` carries an example answer**, in the
81
+ form that can be checked beside the form that cannot. A question that takes
82
+ five minutes of thought to parse gets a worse answer than the same question
83
+ with an example attached.
84
+ - **Adopting Jig in a project that already has CSS.** The README now says
85
+ plainly what happens: the rules are read before anything is written, the
86
+ token layer is wired how you choose, and there are four ways in — one page
87
+ start to finish, a large codebase, only the new pages, and a page you
88
+ already have. Redesigning an existing page is its own path, and `spec` asks
89
+ different questions when the page exists.
90
+
3
91
  ## 0.13.0
4
92
 
5
93
  Meaning before presentation, and one fewer step anyone can skip.
package/README.md CHANGED
@@ -12,13 +12,13 @@ Installed as `npx jig-ui` — the bare name was taken on npm.
12
12
  Jig is **a skill your coding agent reads**, and **a CLI you can run yourself**.
13
13
  They are two halves of the same thing, and the split is not arbitrary:
14
14
 
15
- - Of the 115 rules, **18 can be decided by a machine** — a hard-coded colour, a
15
+ - Of the 130 rules, **26 can be decided by a machine** — a hard-coded colour, a
16
16
  contrast ratio below the floor, a removed focus ring. The CLI decides those.
17
- - The other **97 are judgment** — whether an empty state says anything useful,
17
+ - The other **104 are judgment** — whether an empty state says anything useful,
18
18
  whether a label reads as an instruction, whether motion earns its place. No
19
19
  regex settles those. An agent reads the rules and applies them.
20
20
 
21
- Running only the CLI gets you the 18. Running only the agent gets you the 97 with
21
+ Running only the CLI gets you the 26. Running only the agent gets you the 104 with
22
22
  no verification. **A clean `jig check` is not a clean review**, and the skill
23
23
  says so to every agent that reads it.
24
24
 
@@ -117,6 +117,183 @@ jig.config.json route → mode map
117
117
  Nothing you wrote is touched beyond that one import line. Re-running `init`
118
118
  never overwrites a config or brand file you have edited.
119
119
 
120
+ #### Look before you write anything
121
+
122
+ **Start with `npx jig-ui@latest check --all`.** It reads your code as it stands
123
+ and writes nothing at all — no files, no config, no import. You see what Jig
124
+ would say about the project before deciding whether to adopt it.
125
+
126
+ It is a quieter report than people expect, because Jig checks your code against
127
+ its rules, never against its own naming:
128
+
129
+ - **Your token names are yours.** `--ink-900`, `--paper`, `--space-4`: Jig has no
130
+ opinion about what you call things, and no rule asks you to rename anything.
131
+ What it looks for is a reference to a name that nothing in your project
132
+ declares, which is a bug in any codebase.
133
+ - **Rules that need a fact about your project stay silent until they have one.**
134
+ Density and type scale follow the mode, and there is no mode until you declare
135
+ one, so those rules say nothing on a first run.
136
+ - **Hard-coded values are only reported where a token layer exists to bypass.**
137
+ A project with no tokens is not told off for having none.
138
+
139
+ On a tidy existing page with its own tokens, a first run typically reports a
140
+ couple of specific things — a lone hex among a hundred `var()` calls, a repeated
141
+ set of cards with no list element — rather than a wall.
142
+
143
+ #### When you do run `init`
144
+
145
+ The token layer is a set of custom property declarations. Declarations nothing
146
+ references change no pixel, so adding it does not restyle your site.
147
+
148
+ - **Different names never collide.** Your tokens and Jig's sit side by side; each
149
+ is used by whoever asks for it. You can adopt one token at a time, or none.
150
+ - **If a name is the same in both, yours wins.** The import goes above your own
151
+ rules, and the later declaration is the one that applies.
152
+ - **One line does more than declare a token:** `color-scheme: light dark`, which
153
+ tells the browser your page supports both, so scrollbars and form controls
154
+ follow the reader's system setting.
155
+
156
+ #### You decide how it is wired
157
+
158
+ `init`'s default is a convenience for a project with one obvious entry point,
159
+ not a requirement. Every part of it is yours to direct, whether you do it or
160
+ tell your agent to:
161
+
162
+ - **Where the files go.** `brand` in `jig.config.json` sets the token directory.
163
+ Put it wherever your CSS lives.
164
+ - **Whether Jig wires anything at all.** It adds the import only when there is
165
+ one unambiguous entry stylesheet. Otherwise it writes the files, prints the
166
+ line to add, and leaves your CSS alone for you to place.
167
+ - **How it is wired.** The barrel is two `@import`s, brand then mode. Skip it and
168
+ import the two files yourself, take only the brand file, inline them into your
169
+ build, or import a different barrel at each route — which is what a project
170
+ with more than one mode does. `init` names those extra barrels and
171
+ deliberately does not wire them: which entry point serves `/admin` is your
172
+ routing, and it cannot see it.
173
+ - **Your edits survive.** Every file `init` writes is checksummed. Change one and
174
+ `update` leaves it alone and says so, rather than reverting your wiring at the
175
+ next version.
176
+ - **One constraint that is not a preference.** The tokens are declared on
177
+ `:root`, so the layer has to reach the document globally. Imported inside a CSS
178
+ module or a scoped component block, the tokens exist only there. Anywhere
179
+ global is fine.
180
+
181
+ #### One page, start to finish
182
+
183
+ A project with its own tokens, no Jig. Four steps, and the report after each is
184
+ the real output:
185
+
186
+ ```
187
+ $ npx jig-ui@latest check --all
188
+ ✗ H-47 Hard-coded colour `#fff` past the token layer src/app.css:6
189
+ ⚠ H-119 3 sibling article.card elements are a repeated set …
190
+ 1 error, 1 warning · 8 files, 5 with styles
191
+
192
+ $ npx jig-ui@latest install --agent claude # the skill your agent reads
193
+ $ npx jig-ui@latest init --yes # writes the token layer, touches no CSS
194
+ ```
195
+
196
+ `init` here found no single entry stylesheet, so it wrote the files and printed
197
+ the import rather than editing anything. Adding that line yourself, and changing
198
+ one value:
199
+
200
+ ```css
201
+ @import "./jig/theme.css"; /* the line init printed */
202
+ @import "./tokens.css"; /* your tokens, unchanged */
203
+
204
+ .button { background: var(--accent); color: var(--color-on-brand); }
205
+ ```
206
+
207
+ ```
208
+ $ npx jig-ui@latest check --all
209
+ ⚠ H-119 3 sibling article.card elements are a repeated set …
210
+ 0 errors, 1 warning
211
+ ```
212
+
213
+ The error is gone, `--ink-900` and `--paper` and the rest are exactly as they
214
+ were, and the one warning is the judgment call left for you: whether those cards
215
+ are a list. That is the whole loop. Repeat it wherever it is worth repeating.
216
+
217
+ #### A large codebase
218
+
219
+ The first `check --all` on a big repo is a long list, and the list is not a
220
+ to-do. Read it in this order:
221
+
222
+ 1. **`check --all --ci` first.** Mechanical bucket, errors only, exit code you
223
+ can put in CI. It is the short list, and every line on it is decidable.
224
+ 2. **Then warnings, by rule rather than by file.** The report groups by rule id,
225
+ and a rule firing forty times is one decision made once, not forty.
226
+ 3. **Then one page at a time.** `check` defaults to the files you changed, so
227
+ once the first two passes are done it goes quiet and stays that way for
228
+ everything except what you touch.
229
+
230
+ Nothing obliges you to reach zero. A `check` that is quiet on today's diff is
231
+ worth more than one that was quiet on the whole repo six months ago.
232
+
233
+ #### Only the new pages
234
+
235
+ Adopting Jig everywhere is not the price of using it anywhere. The rules apply
236
+ to what you point them at:
237
+
238
+ - **New work follows the loop** — decide, spec, mockup, make, critique — and the
239
+ Stop hook holds it to that, if you asked for the hook.
240
+ - **Old pages sit where they are.** They are not rewritten, and the default
241
+ `check` says nothing about a file nobody has touched.
242
+ - **`jig.config.json` can exempt paths** you have no intention of revisiting, and
243
+ the report names every exemption on every run, so an exemption list cannot grow
244
+ quietly.
245
+ - **The token layer works the same way.** A page adopts a token when someone
246
+ edits it to use one; no page changes on its own.
247
+
248
+ #### A page you already have
249
+
250
+ The loop assumes a page being built. For one that exists, the order changes
251
+ slightly and the commands do not:
252
+
253
+ 1. **`/jig decide`** first, as always: the rules are the system's, the
254
+ decisions are yours, and a review with no decisions to check against is half a
255
+ review.
256
+ 2. **`/jig spec <page>`**, written from the page as built. Your agent
257
+ reads what is there and describes it — regions, hierarchy, navigation at each
258
+ size — and you confirm or correct it. It is a description, not a redesign.
259
+ 3. **`/jig critique`** then has what it needs: the rules, the spec it
260
+ just confirmed, and your decisions. It renders the page, measures it, and
261
+ reports.
262
+ 4. **`/jig make`** fixes what the critique found, and `critique` runs
263
+ again until it is clean or you accept what is left.
264
+
265
+ Skipping step 2 and asking for a critique on its own leaves the review with
266
+ nothing to check the page against except the rules, which is the weakest half of
267
+ what Jig knows about your project.
268
+
269
+ #### Redesigning a page you already have
270
+
271
+ The opposite job, and the loop runs in its ordinary order. The difference is what
272
+ the old page counts as: **content and constraints, not a target.**
273
+
274
+ 1. **Measure the page as it is, first.** `jig probe --run <page> --save <slug>`
275
+ records what it does today at each width — whether it scrolls sideways, whether
276
+ the menu opens, what order it reads in. Keep it. It is the only way to say
277
+ afterwards whether the redesign improved anything or merely changed it.
278
+ 2. **`/jig decide`**, if the project has not.
279
+ 3. **`/jig spec <page>`** as normal, designing forward. Take the **content** from
280
+ the old page — its copy, its real data, the questions its FAQ answers — and
281
+ decide the structure from the rules, not from what the markup happens to do
282
+ now. Anything that genuinely must survive is a constraint, so say so in the
283
+ spec: a URL that is linked from elsewhere, a field order the back end depends
284
+ on, legal wording somebody signed off. Everything else is open.
285
+ 4. **`/jig mockup`**, low fidelity, reviewed before code. This is where a
286
+ redesign is cheap to argue about.
287
+ 5. **`/jig make`** builds it, and **`/jig critique`** checks it against the spec,
288
+ the mockup and your decisions.
289
+
290
+ The trap worth naming: carrying the old structure across because it is there. A
291
+ page redesigned from its own markup ends up the same page with new colours. The
292
+ old page is the brief's content; the rules and the spec decide its shape.
293
+
294
+ Adopting Jig is additive. The pressure to move values into tokens arrives when
295
+ you start using them, not on the day you install.
296
+
120
297
  ### A brand-new site
121
298
 
122
299
  There is no CSS to read, so there is nothing to derive from and nowhere obvious
@@ -180,6 +357,7 @@ overwrites a config or brand file you have edited.
180
357
  | `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. |
181
358
  | `check [--all] [--ci] [--json]` | Runs the rules a machine can decide. Reports findings by rule id. |
182
359
  | `update` | Refreshes an install to a newer version, leaving alone any file you have edited. |
360
+ | `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. |
183
361
  | `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. |
184
362
  | `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. |
185
363
  | `gate` | Run by the Stop hook `install` adds for Claude Code, not by hand. Blocks an agent from finishing while `check` fails on the files it changed, or the step it just ran left its work unfinished. |
@@ -211,11 +389,12 @@ on the result — the CLI reports, the agent applies the judgment half.
211
389
  | Slash command | Equivalent |
212
390
  | --- | --- |
213
391
  | `/jig init` | `jig init` — then states the mode it chose and what it wired |
214
- | `/jig check` | `jig check` — then applies the 97 judgment rules and reports both halves |
392
+ | `/jig check` | `jig check` — then applies the 104 judgment rules and reports both halves |
215
393
  | `/jig explain C-19` | `jig explain C-19` — prints the rule as-is, without paraphrasing it |
216
394
  | `/jig explain contrast` | `jig explain contrast` — every rule matching a word, when you do not have an id |
217
395
  | `/jig install --agent cursor` | `jig install --agent cursor` |
218
396
  | `/jig update` | `jig update` |
397
+ | `/jig seo` | `jig seo` — then reports what a stranger meets before the page, and what one file cannot see |
219
398
  | `/jig decide` | No CLI. Once per project: interviews you and writes the project-wide decisions, with a reason for each |
220
399
  | `/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 |
221
400
  | `/jig mockup` | No CLI. Low-fidelity design of that spec, reviewed before code — in HTML, Figma or Google Stitch, whichever you choose |
@@ -249,6 +428,30 @@ convention for *skills*, not a harness with a command system of its own, so
249
428
  there is no file to write and nothing that would read one. Ask in plain language
250
429
  instead; the skill still loads.
251
430
 
431
+ ## What a search engine reads
432
+
433
+ A page's title, description and preview text are copy, and they drift because a
434
+ copy pass reads pages and nobody reads `<head>`. Jig treats them as copy: the
435
+ spec decides whether a page is indexable and what it claims, `make` writes the
436
+ metadata in the same change as the headline, and `check` holds the budgets.
437
+
438
+ **Which pages are meant to be found is decided by mode, not by taste.**
439
+ `editorial` is first-visit content, so it is indexable and needs its own title
440
+ and description. `product` and `operator` are what somebody reaches after signing
441
+ in, so they must carry `noindex` — an admin screen in a search result is an
442
+ invitation, and a sign-in page in one invites credential stuffing. A spec
443
+ overrides the default per page, with a reason: a CV shared by link, a
444
+ confirmation page, a page written for one recipient.
445
+
446
+ `robots.txt` is not that mechanism. It is public and advisory, and naming a path
447
+ in it tells strangers where to look; a path is safe to name only when something
448
+ else protects it.
449
+
450
+ `jig seo` covers what one file cannot: a route that says `noindex` and sits in
451
+ the sitemap anyway, two pages claiming one title, a sitemap of paths a crawler
452
+ drops. It writes nothing and needs nothing, so it is safe to run on the first
453
+ day, or on somebody else's codebase.
454
+
252
455
  ## Using it with a coding agent
253
456
 
254
457
  `install` puts a skill file where your agent looks, and the rules beside it. From
@@ -351,6 +554,19 @@ guessed at.
351
554
  Anything the suite still cannot read is named in the report, so a narrow pass
352
555
  never reads as a broad one.
353
556
 
557
+ ## What Jig does not check
558
+
559
+ **Security.** There is a small section of rules about what an interface does to
560
+ itself — a new-tab link handing over the window it left, user content written
561
+ into the page as markup, a password field fighting the manager, a third-party
562
+ frame with nothing narrowing it, a secret printed on screen, an error naming the
563
+ stack. That is the interface's own surface, and it is all Jig can see.
564
+
565
+ It knows nothing about sessions, rate limits, CORS origins, secrets, headers,
566
+ dependencies or your hosting's assumptions. A clean `jig check` says nothing
567
+ about any of them, and should never be quoted as if it did. Use something built
568
+ for that, and keep its findings where you keep this one's.
569
+
354
570
  ## Upgrading
355
571
 
356
572
  ```bash
@@ -371,7 +587,7 @@ treatment.
371
587
 
372
588
  | File | Contents |
373
589
  | --- | --- |
374
- | `rules/00-anti-patterns.md` | 97 universal rules with corrections |
590
+ | `rules/00-anti-patterns.md` | 112 universal rules with corrections |
375
591
  | `rules/01-modes.md` | `editorial` / `product` / `operator` profiles |
376
592
  | `rules/02-tokens.md` | Token contract, naming, consumption |
377
593
  | `rules/03-patterns.md` | Component anatomy and behaviour |