jig-ui 0.3.0 → 0.4.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,53 +43,261 @@ 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.
100
+
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.
105
+
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>` | 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. |
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
+ | `check --ci` | Mechanical bucket only — deterministic, and exits non-zero on any error. |
127
+ | `check --json` | Machine-readable findings, for tooling or for reading every finding when the terminal output elides repeats. |
128
+ | `init --yes` | Non-interactive; accept every derived default. |
129
+ | `install --scope global` | Install once for every project. |
130
+
131
+ **Run `update` unpinned:** `npx jig-ui@latest update`. The skill pins every other
132
+ command to the version that wrote it, so the CLI and the rules always agree;
133
+ `update` is the one command whose job is to move that pin, so pinning it would
134
+ mean it could never move.
135
+
136
+ ### As slash commands
137
+
138
+ Every command is also a slash command in your agent, installed alongside the
139
+ skill. `/jig check --all` does what `npx jig-ui check --all` does, and then acts
140
+ on the result — the CLI reports, the agent applies the judgment half.
141
+
142
+ | Slash command | Equivalent |
143
+ | --- | --- |
144
+ | `/jig init` | `jig init` — then states the mode it chose and what it wired |
145
+ | `/jig check` | `jig check` — then applies the 97 judgment rules and reports both halves |
146
+ | `/jig explain C-19` | `jig explain C-19` — prints the rule as-is, without paraphrasing it |
147
+ | `/jig install --agent cursor` | `jig install --agent cursor` |
148
+ | `/jig update` | `jig update` |
149
+
150
+ Where each lands:
151
+
152
+ | Agent | Slash command file | Scope |
153
+ | --- | --- | --- |
154
+ | Claude Code | `.claude/commands/jig.md` | project or global |
155
+ | Cursor | `.cursor/commands/jig.md` | project or global |
156
+ | opencode | `.opencode/command/jig.md` | project or global |
157
+ | Gemini CLI | `.gemini/commands/jig.toml` | project or global |
158
+ | Codex | `~/.codex/prompts/jig.md` | **global only** |
159
+ | Generic | — | none |
160
+
161
+ Two exceptions, both deliberate.
162
+
163
+ **Codex** takes its command globally only: OpenAI documents custom prompts as
164
+ loading from `~/.codex/prompts` with no project-scoped equivalent, so a project
165
+ install writes no prompt file. Its skill works either way — and OpenAI
166
+ deprecates custom prompts in favour of skills for exactly that reason, since a
167
+ skill can be shared through your repository while a prompt stays on one machine.
168
+
169
+ **Generic** gets no slash command at all. `.agents/skills/` is a cross-agent
170
+ convention for *skills*, not a harness with a command system of its own, so
171
+ there is no file to write and nothing that would read one. Ask in plain language
172
+ instead; the skill still loads.
173
+
174
+ ## Using it with a coding agent
175
+
176
+ `install` puts a skill file where your agent looks, and the rules beside it. From
177
+ then on the agent loads the anti-patterns and the mode profile before building
178
+ any UI, takes the mode from `jig.config.json`, loads the pattern section for
179
+ whatever it is building, consumes tokens by name, and cites any rule it
180
+ deliberately breaks.
181
+
182
+ ### Slash commands
183
+
184
+ `install` also writes a `/jig` command, so the CLI is reachable without leaving
185
+ your session:
186
+
187
+ ```
188
+ /jig init /jig check --all /jig update
189
+ ```
190
+
191
+ It runs the CLI and then does the part the CLI cannot — for `/jig check` that
192
+ means applying the 97 judgment rules to the same files and merging both halves
193
+ into one report keyed by rule id.
194
+
195
+ | Harness | Command file |
196
+ | --- | --- |
197
+ | Claude Code | `.claude/commands/jig.md` |
198
+ | Cursor | `.cursor/commands/jig.md` |
199
+ | opencode | `.opencode/command/jig.md` |
200
+ | Gemini CLI | `.gemini/commands/jig.toml` |
201
+ | Codex | — run the CLI directly; see below |
202
+ | Generic | — no harness to register with |
203
+
204
+ Codex's custom prompts are not written: `codex exec` does not expand them, so a
205
+ command file could sit there and never fire. Codex users run
206
+ `npx jig-ui@latest check` directly — the skill in `AGENTS.md` is unaffected.
207
+
208
+ **You still prompt normally.** Ask for a settings page, a data table, an empty
209
+ state — whatever you were going to ask for. What you no longer have to say is
210
+ *how*: "use the design tokens", "handle the loading state", "don't invent a
211
+ colour". That part is the skill's job, and what you get back names its own
212
+ decisions — *"P-02 forbids a column of primaries where an action repeats down a
213
+ list"* rather than "I made the button secondary."
214
+
215
+ Whether the agent picks the skill up on its own depends on the harness. Most
216
+ surface a skill by matching your request against its description, so a request
217
+ that plainly involves UI usually loads it. If it does not, say so once —
218
+ "follow the jig skill" — and it will.
219
+
220
+ Every finished piece of UI work ends with an attestation line:
221
+
222
+ ```text
223
+ JIG_CHECK: version=<version> mode=<mode> mechanical=<pass|fail|skipped>:<n> judgment=<ran|skipped>
224
+ ```
225
+
226
+ `jig check` emits the same line for the half it can do, with `judgment=not-run`.
227
+ If an agent reports `judgment=ran`, it ran the self-check at the end of
228
+ `rules/00-anti-patterns.md`; if it says `skipped`, it must say why.
229
+
230
+ ## Using it from the command line
231
+
232
+ No agent required. `check` is a linter with a design system behind it.
233
+
234
+ ```bash
235
+ npx jig-ui@latest check --all # everything
236
+ npx jig-ui@latest check # just what changed
237
+ npx jig-ui@latest check --ci # for CI: deterministic, non-zero on error
238
+ npx jig-ui@latest check --json # for tooling
239
+ ```
240
+
241
+ In CI:
242
+
243
+ ```yaml
244
+ - run: npx jig-ui@latest check --ci
245
+ ```
246
+
247
+ `--ci` restricts to the mechanical bucket, so the result depends only on your
248
+ code — nothing model-dependent, no network. As a pre-commit hook, plain `check`
249
+ looks at changed files only.
250
+
251
+ What you will not get from the CLI alone is the other 97 rules. `check` says so
252
+ rather than letting a narrow pass read as a broad one.
253
+
254
+ ## What `check` covers
255
+
256
+ It reads CSS wherever it lives:
257
+
258
+ | Where | Example |
259
+ | --- | --- |
260
+ | Stylesheets | `.css`, `.scss`, `.less` |
261
+ | `<style>` blocks | HTML, Astro, Vue, Svelte, PHP, ERB, Twig, Handlebars, MDX, ASP/ASP.NET, Razor, JSP, Phoenix, EJS, Nunjucks, Liquid, Jinja, Velocity, FreeMarker |
262
+ | Indented style blocks | Pug (`style.`), Haml (`:css`), Slim (`css:`) |
263
+ | Style attributes | `style="color: #777"`, `style={{ color: '#777' }}` |
264
+ | CSS-in-JS | `styled.button\`…\``, `styled(Link)\`…\``, `css\`…\``, `createGlobalStyle`, `keyframes` |
265
+ | Tailwind arbitrary values | `className="bg-[#6D28D9] p-[13px]"` |
266
+ | Tailwind palette pairs | `className="bg-white text-gray-400"` |
267
+
268
+ Host files are reduced to their style regions before the detectors run, with
269
+ character positions preserved, so a finding's line points at the real line in
270
+ your `.vue` or `.tsx` file. Application code outside a style region is never read
271
+ as CSS.
272
+
273
+ The seven mechanical rules: hard-coded values past the token layer (`H-47`),
274
+ contrast below the floor (`C-19`), removed focus rings (`E-29`), gradient text
275
+ (`A-02`), backdrop blur (`A-04`), pure black and white (`C-18`), and the
276
+ violet-band hue check (`A-01`, which asks rather than fails).
277
+
278
+ Two deliberate limits. A bare `p-4` is **not** a finding — it resolves through a
279
+ scale, which is what a scale is for, and the scale is your project's decision.
280
+ And a colour outside the framework's default palette is not resolved rather than
281
+ guessed at.
282
+
283
+ Anything the suite still cannot read is named in the report, so a narrow pass
284
+ never reads as a broad one.
285
+
286
+ ## Upgrading
287
+
288
+ ```bash
289
+ npx jig-ui@latest update
290
+ ```
291
+
292
+ Files you have edited are left alone. Upgrading from a pre-0.4.0 install that
293
+ vendored rules into your project's `.jig/`? `init` and `check` detect the
294
+ leftover files, report them, and — with your consent, and never for a file you
295
+ have edited — offer to remove just the install artifacts, keeping your tokens
296
+ and config untouched.
297
+
298
+ Cursor's skill moved from `.cursor/rules/jig.mdc` to
299
+ `.cursor/skills/jig/SKILL.md`; `init` finds the old file and offers the same
300
+ treatment.
67
301
 
68
302
  ## Files
69
303
 
@@ -78,6 +312,9 @@ derived default non-interactively (the mode CI and agents run in). Re-running
78
312
  | `.jig/tokens/brand.*.css` | Identity. One per project. | Imported by the app |
79
313
  | `.jig/tokens/mode.*.css` | Density, scale, rhythm, motion | One per surface |
80
314
 
315
+ `rules/*` and `rules.index.json` live beside your installed skill file, not
316
+ in the project — see above.
317
+
81
318
  `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.
82
319
 
83
320
  ## Per-project declaration