jig-ui 0.3.0 → 0.5.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/README.md CHANGED
@@ -2,11 +2,37 @@
2
2
 
3
3
  A design system written to be consumed by coding agents, not read by designers.
4
4
 
5
- Installed as `npx jig-ui` — the bare name was taken on npm.
6
-
7
5
  Framework-agnostic. Tokens are CSS custom properties; rules are stated in CSS
8
6
  properties and behaviour, never in one framework's class names.
9
7
 
8
+ Installed as `npx jig-ui` — the bare name was taken on npm.
9
+
10
+ ## Two ways to use it
11
+
12
+ Jig is **a skill your coding agent reads**, and **a CLI you can run yourself**.
13
+ They are two halves of the same thing, and the split is not arbitrary:
14
+
15
+ - Of the 104 rules, **7 can be decided by a machine** — a hard-coded colour, a
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,
18
+ whether a label reads as an instruction, whether motion earns its place. No
19
+ regex settles those. An agent reads the rules and applies them.
20
+
21
+ Running only the CLI gets you the 7. Running only the agent gets you the 97 with
22
+ no verification. **A clean `jig check` is not a clean review**, and the skill
23
+ says so to every agent that reads it.
24
+
25
+ ## Quick start
26
+
27
+ ```bash
28
+ npx jig-ui@latest install --agent claude # put the skill where your agent finds it
29
+ npx jig-ui@latest init # set this project up
30
+ npx jig-ui@latest check --all # see where you stand
31
+ ```
32
+
33
+ Then ask your agent to build something. It reads the rules from the install and
34
+ cites them.
35
+
10
36
  ## Install
11
37
 
12
38
  Paste the line for your agent and let it run the command.
@@ -17,68 +43,255 @@ Paste the line for your agent and let it run the command.
17
43
  | Codex | `npx jig-ui@latest install --agent codex` |
18
44
  | Cursor | `npx jig-ui@latest install --agent cursor` |
19
45
  | opencode | `npx jig-ui@latest install --agent opencode` |
46
+ | Gemini CLI | `npx jig-ui@latest install --agent gemini` |
20
47
  | Any other agent | `npx jig-ui@latest install --agent generic` |
21
48
 
22
- Add `--scope global` to install once for every project instead of just this
23
- one. Where a global install lands depends on the agent:
49
+ Add `--scope global` to install once for every project instead of just this one.
50
+ Every agent supports both scopes.
24
51
 
25
52
  | Agent | Project scope | Global scope |
26
53
  | --- | --- | --- |
27
54
  | Claude Code | `.claude/skills/jig/SKILL.md` | `~/.claude/skills/jig/SKILL.md` |
28
- | Codex | `AGENTS.md` | `~/.codex/AGENTS.md` |
29
- | Cursor | `.cursor/rules/jig.mdc` | not supported |
55
+ | Codex | `.agents/skills/jig/SKILL.md` | `~/.agents/skills/jig/SKILL.md` |
56
+ | Cursor | `.cursor/skills/jig/SKILL.md` | `~/.cursor/skills/jig/SKILL.md` |
30
57
  | opencode | `.opencode/skills/jig/SKILL.md` | `~/.config/opencode/skills/jig/SKILL.md` |
31
- | Generic | `AGENTS.md` | not supported |
58
+ | Gemini CLI | `.gemini/skills/jig/SKILL.md` | `~/.gemini/skills/jig/SKILL.md` |
59
+ | Generic | `.agents/skills/jig/SKILL.md` | `~/.agents/skills/jig/SKILL.md` |
32
60
 
33
- In both scopes, the rules themselves are vendored to `<root>/.jig/` — the
34
- project root for a project-scoped install, or your home directory for a
35
- global one.
61
+ Every agent reads a `skills/jig/SKILL.md`, so adding a new harness is a config
62
+ change rather than a new code path. Codex uses the cross-agent `.agents/`
63
+ directory and additionally gets a short pointer block in `AGENTS.md` — that file
64
+ is read into every session, so it names the skill rather than restating it.
36
65
 
37
- Update later with `npx jig-ui@latest update` — files you have edited are left
38
- alone.
66
+ Install writes the skill file **and its rules** to one place only — beside the
67
+ skill file itself. Nothing of Jig's is vendored into your repo; your agent reads
68
+ the rules from the install. Installing at project scope when the same agent is
69
+ already installed globally warns rather than creating a second, contradicting
70
+ skill.
39
71
 
40
- Install writes the rules and the design tokens into `.jig/`. Import the tokens
41
- your surface needs — one brand file, one mode file:
72
+ ## Set the project up
42
73
 
43
- ```css
44
- @import ".jig/tokens/brand.default.css";
45
- @import ".jig/tokens/mode.product.css";
74
+ ```bash
75
+ npx jig-ui@latest init
46
76
  ```
47
77
 
48
- Copy `brand.default.css` to `brand.<yourproject>.css` and edit that; `jig update`
49
- will not overwrite a file you have changed.
78
+ `init` is the only command that writes into your repo. It detects your CSS
79
+ system (Tailwind v4, Tailwind v3, plain CSS), derives a brand colour from what
80
+ your project already has — custom properties first, then a Tailwind config, then
81
+ the most frequent literal colour — rather than interviewing you cold, validates
82
+ that colour against the contrast and collision requirements in Jig's own brand
83
+ file, writes the token files, wires the `@import`s into your stylesheet when
84
+ there is one unambiguous place for them, and runs a baseline `check` so you have
85
+ a number to move.
50
86
 
51
- Or let `jig init` do the above for you:
87
+ A single-mode project ends up with four files, all of them yours:
52
88
 
53
89
  ```
54
- npx jig-ui@latest init
90
+ jig.config.json route → mode map
91
+ .jig/
92
+ state.json bookkeeping — version, modes in use, checksums
93
+ tokens/
94
+ brand.<project>.css your identity, edit freely
95
+ <mode>.css a copy of Jig's mode file, refreshed by `update`
55
96
  ```
56
97
 
57
- It detects your CSS system (Tailwind v4, Tailwind v3, plain CSS), derives a
58
- brand colour from what your project already has (custom properties first,
59
- then a Tailwind config, then the most frequent literal colour) instead of
60
- asking cold, validates that colour against the contrast and collision
61
- requirements stated in `brand.default.css` itself, writes
62
- `.jig/tokens/brand.<project>.css` and `jig.config.json`, wires the `@import`
63
- into your stylesheet when there is one unambiguous place to put it, and runs
64
- a baseline `check` so you have a number to move. Add `--yes` to accept every
65
- derived default non-interactively (the mode CI and agents run in). Re-running
66
- `init` never overwrites a `jig.config.json` or brand file you have edited.
98
+ The mode file is the one thing genuinely copied: a stylesheet `@import` is an
99
+ edge in a build graph and has to resolve locally, on every machine that builds.
67
100
 
68
- ## Files
101
+ **Commit `.jig/`.** It holds the token files your stylesheet imports, so a
102
+ gitignored `.jig/` means the design system does not exist for anyone who did not
103
+ run `init` themselves — their build breaks on a missing import, and CI's `jig
104
+ check` sees no token layer at all. `init` warns if it finds `.jig/` ignored.
69
105
 
70
- | File | Contents | Load |
106
+ Add `--yes` to accept every derived default non-interactively — the mode CI and
107
+ agents run in. It states the mode it chose and where to change it, because
108
+ `jig.config.json` outranks an agent's own inference. Re-running `init` never
109
+ overwrites a config or brand file you have edited.
110
+
111
+ ## Commands
112
+
113
+ | Command | What it does |
114
+ | --- | --- |
115
+ | `install --agent <name> [--scope project\|global]` | Puts the skill and its rules where your agent will find them. Writes nothing else into your repo. |
116
+ | `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. |
117
+ | `check [--all] [--ci] [--json]` | Runs the rules a machine can decide. Reports findings by rule id. |
118
+ | `update` | Refreshes an install to a newer version, leaving alone any file you have edited. |
119
+ | `explain <rule-id \| word> [--list]` | Given an id, prints a rule in full — what it forbids, what to do instead, the version it arrived in, and who checks it. Also resolves the `P-` pattern and `M-` mode specs, which no rule index contains. Given a **word**, searches every title and body and lists what matches, so you can find a rule you cannot name. `--list` prints every id, or one section's. |
120
+
121
+ Flags worth knowing:
122
+
123
+ | Flag | Effect |
124
+ | --- | --- |
125
+ | `check --all` | Scan the whole repo instead of just changed files. Use on a first run. |
126
+ | `explain --list` | Every rule id and title. Add a section letter (`explain G --list`) for one section. |
127
+ | `check --ci` | Mechanical bucket only — deterministic, and exits non-zero on any error. |
128
+ | `check --json` | Machine-readable findings, for tooling or for reading every finding when the terminal output elides repeats. |
129
+ | `init --yes` | Non-interactive; accept every derived default. |
130
+ | `install --scope global` | Install once for every project. |
131
+
132
+ **Run `update` unpinned:** `npx jig-ui@latest update`. The skill pins every other
133
+ command to the version that wrote it, so the CLI and the rules always agree;
134
+ `update` is the one command whose job is to move that pin, so pinning it would
135
+ mean it could never move.
136
+
137
+ ### As slash commands
138
+
139
+ Every command is also a slash command in your agent, installed alongside the
140
+ skill. `/jig check --all` does what `npx jig-ui check --all` does, and then acts
141
+ on the result — the CLI reports, the agent applies the judgment half.
142
+
143
+ | Slash command | Equivalent |
144
+ | --- | --- |
145
+ | `/jig init` | `jig init` — then states the mode it chose and what it wired |
146
+ | `/jig check` | `jig check` — then applies the 97 judgment rules and reports both halves |
147
+ | `/jig explain C-19` | `jig explain C-19` — prints the rule as-is, without paraphrasing it |
148
+ | `/jig explain contrast` | `jig explain contrast` — every rule matching a word, when you do not have an id |
149
+ | `/jig install --agent cursor` | `jig install --agent cursor` |
150
+ | `/jig update` | `jig update` |
151
+
152
+ Where each lands:
153
+
154
+ | Agent | Slash command file | Scope |
71
155
  | --- | --- | --- |
72
- | `rules/00-anti-patterns.md` | 87 universal rules with corrections | **Always** |
73
- | `rules/01-modes.md` | `editorial` / `product` / `operator` profiles | **Always** |
74
- | `rules/02-tokens.md` | Token contract, naming, consumption | On setup, or when adding a token |
75
- | `rules/03-patterns.md` | Component anatomy and behaviour | When building a covered pattern |
76
- | `rules/04-principles.md` | Five frames + seven tiebreakers | Novel decisions, or rule conflicts |
77
- | `rules/05-copy.md` | Interface text rules | Writing any user-facing string |
78
- | `.jig/tokens/brand.*.css` | Identity. One per project. | Imported by the app |
79
- | `.jig/tokens/mode.*.css` | Density, scale, rhythm, motion | One per surface |
156
+ | Claude Code | `.claude/commands/jig.md` | project or global |
157
+ | Cursor | `.cursor/commands/jig.md` | project or global |
158
+ | opencode | `.opencode/command/jig.md` | project or global |
159
+ | Gemini CLI | `.gemini/commands/jig.toml` | project or global |
160
+ | Codex | `~/.codex/prompts/jig.md` | **global only** |
161
+ | Generic | — | none |
162
+
163
+ Two exceptions, both deliberate.
164
+
165
+ **Codex** takes its command globally only: OpenAI documents custom prompts as
166
+ loading from `~/.codex/prompts` with no project-scoped equivalent, so a project
167
+ install writes no prompt file. Its skill works either way — and OpenAI
168
+ deprecates custom prompts in favour of skills for exactly that reason, since a
169
+ skill can be shared through your repository while a prompt stays on one machine.
170
+
171
+ **Generic** gets no slash command at all. `.agents/skills/` is a cross-agent
172
+ convention for *skills*, not a harness with a command system of its own, so
173
+ there is no file to write and nothing that would read one. Ask in plain language
174
+ instead; the skill still loads.
175
+
176
+ ## Using it with a coding agent
177
+
178
+ `install` puts a skill file where your agent looks, and the rules beside it. From
179
+ then on the agent loads the anti-patterns and the mode profile before building
180
+ any UI, takes the mode from `jig.config.json`, loads the pattern section for
181
+ whatever it is building, consumes tokens by name, and cites any rule it
182
+ deliberately breaks.
183
+
184
+ **You still prompt normally.** Ask for a settings page, a data table, an empty
185
+ state — whatever you were going to ask for. What you no longer have to say is
186
+ *how*: "use the design tokens", "handle the loading state", "don't invent a
187
+ colour". That part is the skill's job, and what you get back names its own
188
+ decisions — *"P-02 forbids a column of primaries where an action repeats down a
189
+ list"* rather than "I made the button secondary."
190
+
191
+ Whether the agent picks the skill up on its own depends on the harness. Most
192
+ surface a skill by matching your request against its description, so a request
193
+ that plainly involves UI usually loads it. If it does not, say so once —
194
+ "follow the jig skill" — and it will.
195
+
196
+ Every finished piece of UI work ends with an attestation line:
197
+
198
+ ```text
199
+ JIG_CHECK: version=<version> mode=<mode> mechanical=<pass|fail|skipped>:<n> judgment=<ran|skipped>
200
+ ```
201
+
202
+ `jig check` emits the same line for the half it can do, with `judgment=not-run`.
203
+ If an agent reports `judgment=ran`, it ran the self-check at the end of
204
+ `rules/00-anti-patterns.md`; if it says `skipped`, it must say why.
80
205
 
81
- `00` and `01` are the always-loaded core and are sized to stay cheap in context. `03` is the largest file and should be loaded per-pattern rather than wholesale.
206
+ ## Using it from the command line
207
+
208
+ No agent required. `check` is a linter with a design system behind it.
209
+
210
+ ```bash
211
+ npx jig-ui@latest check --all # everything
212
+ npx jig-ui@latest check # just what changed
213
+ npx jig-ui@latest check --ci # for CI: deterministic, non-zero on error
214
+ npx jig-ui@latest check --json # for tooling
215
+ ```
216
+
217
+ In CI:
218
+
219
+ ```yaml
220
+ - run: npx jig-ui@latest check --ci
221
+ ```
222
+
223
+ `--ci` restricts to the mechanical bucket, so the result depends only on your
224
+ code — nothing model-dependent, no network. As a pre-commit hook, plain `check`
225
+ looks at changed files only.
226
+
227
+ What you will not get from the CLI alone is the other 97 rules. `check` says so
228
+ rather than letting a narrow pass read as a broad one.
229
+
230
+ ## What `check` covers
231
+
232
+ It reads CSS wherever it lives:
233
+
234
+ | Where | Example |
235
+ | --- | --- |
236
+ | Stylesheets | `.css`, `.scss`, `.less` |
237
+ | `<style>` blocks | HTML, Astro, Vue, Svelte, PHP, ERB, Twig, Handlebars, MDX, ASP/ASP.NET, Razor, JSP, Phoenix, EJS, Nunjucks, Liquid, Jinja, Velocity, FreeMarker |
238
+ | Indented style blocks | Pug (`style.`), Haml (`:css`), Slim (`css:`) |
239
+ | Style attributes | `style="color: #777"`, `style={{ color: '#777' }}` |
240
+ | CSS-in-JS | `styled.button\`…\``, `styled(Link)\`…\``, `css\`…\``, `createGlobalStyle`, `keyframes` |
241
+ | Tailwind arbitrary values | `className="bg-[#6D28D9] p-[13px]"` |
242
+ | Tailwind palette pairs | `className="bg-white text-gray-400"` |
243
+
244
+ Host files are reduced to their style regions before the detectors run, with
245
+ character positions preserved, so a finding's line points at the real line in
246
+ your `.vue` or `.tsx` file. Application code outside a style region is never read
247
+ as CSS.
248
+
249
+ The seven mechanical rules: hard-coded values past the token layer (`H-47`),
250
+ contrast below the floor (`C-19`), removed focus rings (`E-29`), gradient text
251
+ (`A-02`), backdrop blur (`A-04`), pure black and white (`C-18`), and the
252
+ violet-band hue check (`A-01`, which asks rather than fails).
253
+
254
+ Two deliberate limits. A bare `p-4` is **not** a finding — it resolves through a
255
+ scale, which is what a scale is for, and the scale is your project's decision.
256
+ And a colour outside the framework's default palette is not resolved rather than
257
+ guessed at.
258
+
259
+ Anything the suite still cannot read is named in the report, so a narrow pass
260
+ never reads as a broad one.
261
+
262
+ ## Upgrading
263
+
264
+ ```bash
265
+ npx jig-ui@latest update
266
+ ```
267
+
268
+ Files you have edited are left alone. Upgrading from a pre-0.4.0 install that
269
+ vendored rules into your project's `.jig/`? `init` and `check` detect the
270
+ leftover files, report them, and — with your consent, and never for a file you
271
+ have edited — offer to remove just the install artifacts, keeping your tokens
272
+ and config untouched.
273
+
274
+ Cursor's skill moved from `.cursor/rules/jig.mdc` to
275
+ `.cursor/skills/jig/SKILL.md`; `init` finds the old file and offers the same
276
+ treatment.
277
+
278
+ ## Files
279
+
280
+ | File | Contents |
281
+ | --- | --- |
282
+ | `rules/00-anti-patterns.md` | 87 universal rules with corrections |
283
+ | `rules/01-modes.md` | `editorial` / `product` / `operator` profiles |
284
+ | `rules/02-tokens.md` | Token contract, naming, consumption |
285
+ | `rules/03-patterns.md` | Component anatomy and behaviour |
286
+ | `rules/04-principles.md` | Five frames + seven tiebreakers |
287
+ | `rules/05-copy.md` | Interface text rules |
288
+ | `.jig/tokens/brand.*.css` | Identity. One per project. |
289
+ | `.jig/tokens/mode.*.css` | Density, scale, rhythm, motion |
290
+
291
+ `rules/*` and `rules.index.json` live beside your installed skill file, not
292
+ in the project — see above.
293
+
294
+ Which of these an agent loads, and when, is `AGENTS.md`.
82
295
 
83
296
  ## Per-project declaration
84
297
 
@@ -107,36 +320,7 @@ Without this file, follow the selection procedure in `rules/01-modes.md`: infer,
107
320
 
108
321
  Then `var(--color-text-strong)`, `var(--spacing-card)`, `var(--text-body)` in any framework. For Tailwind v4, wrap both imports in `@theme` to generate utilities. See `rules/02-tokens.md`.
109
322
 
110
- ## Testing that the rules work
111
-
112
- The system is only worth its context cost if it changes output. Test it rather than assuming.
113
-
114
- 1. Pick a task with known failure modes — a form with validation, or a data table with an empty state.
115
- 2. Run it twice: once with the system loaded, once without.
116
- 3. Diff the output against the self-check in `00`.
117
-
118
- A rule that does not change the output is either already the model's default (delete it) or too vague to act on (make it specific). Both are fixes to this system, not to the prompt.
119
-
120
- Re-run after any significant edit to `00` or `03`.
121
-
122
- ## Changing a rule
123
-
124
- - Values change in the token files, never at the call site.
125
- - Rules change in `00`–`03`, never by exception in a project.
126
- - A rule that needs an exception in two projects is wrong; fix the rule.
127
- - Anything mode-dependent belongs in a mode profile, not in `00`.
128
- - A new pattern earns a place in `03` after being built three times.
129
-
130
- ## Sources
131
-
132
- Written from general UI and accessibility practice, plus the constraints specific to agent-generated output — which is where most of the structure comes from: the anti-patterns-first ordering, the mode split, the brand × mode token architecture, and the decidability test applied to every rule.
133
-
134
- **The numeric defaults are being reconciled.** Type scale, spacing steps, control sizes
135
- and motion durations started as internally consistent guesses and are being checked, row by
136
- row, against an external reference on interface design. `RECONCILE.md` tracks the status of
137
- each: adopted, deliberately kept different, or still open. The accessibility floors are
138
- outside that process — contrast ratios and target sizes come from WCAG 2.1 AA and are not
139
- adjustable.
323
+ ---
140
324
 
141
- principles.design informed the rules-versus-principles split, and the standard
142
- `rules/04-principles.md` is held to.
325
+ Working on Jig itself rather than with it: `AGENTS.md` for how an agent should
326
+ change the rules, `RECONCILE.md` for where each numeric default came from.