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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jig-ui",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A design system for coding agents. 104 numbered UI rules, brand x mode design tokens, and an installer for Claude Code, Codex, Cursor and opencode.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -12,6 +12,7 @@
12
12
  "rules",
13
13
  "tokens",
14
14
  "templates",
15
+ "references",
15
16
  "rules.index.json",
16
17
  "LICENSE",
17
18
  "NOTICE",
@@ -260,7 +260,7 @@ Agents render the happy path. This section exists because that is the single mos
260
260
 
261
261
  ### E-29 Focus removed without replacement
262
262
  ❌ `outline: none` with nothing in its place
263
- ✅ A `:focus-visible` rule with a visible indicator built on `--color-focus`. Never remove the outline without replacing it. This locks out every keyboard user, and it is the most common accessibility failure in generated code.
263
+ ✅ A `:focus-visible` rule with a visible indicator built on `--color-focus`, at `--focus-ring-width` with `--focus-ring-offset`. Never remove the outline without replacing it. This locks out every keyboard user, and it is the most common accessibility failure in generated code.
264
264
 
265
265
  ### E-30 Empty states omitted
266
266
  ❌ A table that renders an empty `<tbody>` when there is no data
@@ -119,6 +119,8 @@ Names align to Tailwind v4's theme namespaces. This is free for other frameworks
119
119
  | `--tracking-*` | Letter spacing | mode |
120
120
  | `--spacing-*` | Spacing values | mode |
121
121
  | `--radius-*` | Corner radii | brand scale, mode selection |
122
+ | `--border-width-*` | Stroke widths | brand options, mode selection |
123
+ | `--focus-ring-*` | Focus indicator geometry | brand — an accessibility floor, so not mode-negotiable |
122
124
  | `--shadow-*` | Elevation | brand |
123
125
  | `--duration-*`, `--ease-*` | Motion | mode |
124
126
  | `--size-*` | Control and row heights | mode |
@@ -0,0 +1,74 @@
1
+ The user invoked `{{command_prefix}}{{args_placeholder}}`. Treat
2
+ `{{args_placeholder}}` as the subcommand and its flags.
3
+
4
+ Available subcommands: {{subcommand_list}}. If it is empty or is not one of
5
+ these, say so, list them, and stop.
6
+
7
+ Run the matching CLI command with `{{scripts_path}}`, passing the flags through
8
+ unchanged. Then do the work below for that subcommand. Read the command's full
9
+ output — findings are ordered by severity, not position, so `head`, `tail`,
10
+ `grep` and `jq` drop the ones that matter.
11
+
12
+ ## init
13
+
14
+ Report what it detected, the brand colour it derived and where that came from,
15
+ and the mode it wrote. The mode is the load-bearing decision: `jig.config.json`
16
+ outranks your own inference from then on, so if the project's signals point
17
+ elsewhere — the mode table in `{{rules_path}}/01-modes.md` — say so and ask
18
+ before leaving it.
19
+
20
+ If the token layer does not exist yet, this is the command that creates it. Do
21
+ not author token values yourself under any circumstances.
22
+
23
+ ## check
24
+
25
+ The CLI decides the rules a machine can decide. **It is half the review**, and
26
+ its own attestation says `judgment=not-run` to make that explicit.
27
+
28
+ Do the other half yourself:
29
+
30
+ 1. Load `{{rules_path}}/00-anti-patterns.md` and `{{rules_path}}/05-copy.md`,
31
+ plus the relevant section of `{{rules_path}}/03-patterns.md` for whatever the
32
+ changed files build.
33
+ 2. Apply the judgment rules to the same files the CLI just scanned.
34
+ 3. Merge both halves into **one** report keyed by rule id, ordered by severity —
35
+ not two lists. A reader should not have to know which half found what.
36
+ 4. Run the self-check at the end of `{{rules_path}}/00-anti-patterns.md`.
37
+
38
+ Then emit the attestation with both halves filled in:
39
+
40
+ ```text
41
+ JIG_CHECK: version=<version> mode=<mode> mechanical=<pass|fail|skipped>:<n> judgment=<ran|skipped>
42
+ ```
43
+
44
+ Take `mechanical=` from the CLI's own line. If `check` could not run, that is
45
+ `mechanical=skipped:0` — never `pass`, which would report a clean result for a
46
+ check that inspected nothing. Report `judgment=ran` only if you did step 2.
47
+
48
+ ## install
49
+
50
+ Report where the skill landed and at which scope. If it warned that a global
51
+ install already exists, do not work around it — that warning is the system
52
+ refusing to leave two contradictory skills for one harness.
53
+
54
+ ## explain
55
+
56
+ Print the CLI's output as it stands. It is already the rule's full text — do not
57
+ summarise it, and do not paraphrase the correction into your own words: the
58
+ wording is the rule.
59
+
60
+ If the id is a `P-` or `M-` spec, the output says it is a specification rather
61
+ than a rule, with no ❌/✅ pair and no detector. That is correct, not a gap.
62
+
63
+ If the id does not exist, the error names every id in that section. Offer the
64
+ nearest one rather than guessing what the user meant.
65
+
66
+ ## update
67
+
68
+ Report what moved and what was left alone. Files reported as skipped were edited
69
+ locally and are the user's; never re-apply Jig's version over them.
70
+
71
+ ---
72
+
73
+ Everything in `{{rules_path}}/` is yours to read. Cite rules by id, and cite any
74
+ rule you deliberately break with the reason, in one line.
@@ -3,15 +3,22 @@ cite the number when you follow or deliberately break one.
3
3
 
4
4
  ## Before generating or reviewing any UI
5
5
 
6
+ 0. Check that `{{config_file}}` exists. If it does not, this project has no
7
+ token layer: run `init` and stop until it has been run. Do not proceed by
8
+ writing token definitions of your own — a `:root` block you author, however
9
+ clearly you label it, is an invented design system wearing this one's names,
10
+ and it will not be replaced when the real tokens arrive.
6
11
  1. Load `{{rules_path}}/00-anti-patterns.md` and `{{rules_path}}/01-modes.md`.
7
12
  2. Determine the mode from `{{config_file}}`, or infer it using the procedure in
8
13
  `{{rules_path}}/01-modes.md` and state the inference in one line before building.
9
14
  3. Load the relevant section of `{{rules_path}}/03-patterns.md` for the component you are building.
10
15
  4. Load `{{rules_path}}/05-copy.md` whenever you write a label, button, heading, error or empty state.
11
16
  5. Consume tokens by semantic name only. Never write a raw colour or pixel value
12
- at a call site.
13
- 6. Run the self-check at the end of `{{rules_path}}/00-anti-patterns.md` before finishing
14
- (a future `check` command will automate this).
17
+ at a call site, and never resolve a name yourself: if a token you need has no
18
+ value, that is a finding to report, not a number to supply.
19
+ 6. Run `check` for the rules the CLI can detect, then run the self-check at the
20
+ end of `{{rules_path}}/00-anti-patterns.md` for the rules it cannot. Both
21
+ halves, every time — a clean `check` is not a clean review.
15
22
  7. Cite any rule you deliberately break, with the reason, in one line.
16
23
 
17
24
  Load `{{rules_path}}/04-principles.md` only when two rules conflict.
@@ -20,9 +27,15 @@ Load `{{rules_path}}/04-principles.md` only when two rules conflict.
20
27
 
21
28
  {{available_commands}}
22
29
 
23
- Commands marked `available` run via the CLI at `{{scripts_path}}`. Commands
24
- marked `planned` are listed for context only — running one errors out, since
25
- it is not yet registered.
30
+ Commands marked `available` run via the CLI at `{{scripts_path}}` — the version
31
+ this skill was installed with, so the CLI and these rules always agree.
32
+
33
+ `update` is the exception: its job is to move that version forward, so run it
34
+ as `{{update_path}} update`. Run pinned, it refreshes to the version already
35
+ installed and reports success for a no-op.
36
+
37
+ Commands marked `planned` are listed for context only — running one errors out,
38
+ since it is not yet registered.
26
39
 
27
40
  ## Reading command output
28
41
 
@@ -42,12 +55,14 @@ changed since, do not re-run it.
42
55
  Before you finish a task that generated or modified UI, emit this line:
43
56
 
44
57
  ```text
45
- JIG_CHECK: version=<version> mode=<mode> self_check=<ran|skipped>
58
+ JIG_CHECK: version=<version> mode=<mode> mechanical=<pass|fail|skipped>:<n> judgment=<ran|skipped>
46
59
  ```
47
60
 
48
- <!-- `mechanical=<pass|fail>:<n>/<total>` and `judgment=<ran|skipped>` fields
49
- belong here once the `check` command lands and can actually produce
50
- them — do not add them back before that. -->
61
+ `jig check` emits this same line for the half it can do, with
62
+ `judgment=not-run`. Take `mechanical=` from its output rather than counting by
63
+ hand; fill `judgment=` yourself. If `check` could not run at all, that is
64
+ `mechanical=skipped:0` — never `pass`, which would report a clean result for a
65
+ check that never inspected anything.
51
66
 
52
- A skipped self-check must say `skipped` and give the reason. Do not report
53
- `ran` for a check you did not perform.
67
+ A skipped check must say `skipped` and give the reason. Do not report `ran` for
68
+ a check you did not perform.
@@ -15,13 +15,13 @@
15
15
  "status": "available"
16
16
  },
17
17
  "check": {
18
- "description": "Check changed files or a named target against the rule set. Reports violations by rule id.",
19
- "argumentHint": "[target]",
20
- "status": "planned"
18
+ "description": "Check the repo against the mechanical and hybrid rules the CLI can detect. Reports findings by rule id; the judgment rules remain yours to apply.",
19
+ "argumentHint": "[--all] [--ci] [--json]",
20
+ "status": "available"
21
21
  },
22
22
  "explain": {
23
- "description": "Print a rule's full text, its correction, and the version it was introduced in.",
23
+ "description": "Print a rule's full text, its correction, the version it arrived in, and who checks it. Also resolves the P-/M- pattern and mode specs, which no rule index contains.",
24
24
  "argumentHint": "<rule-id>",
25
- "status": "planned"
25
+ "status": "available"
26
26
  }
27
27
  }
@@ -99,6 +99,23 @@
99
99
 
100
100
  --color-focus: var(--color-text-strong);
101
101
 
102
+ /* ---- Stroke widths. Options; modes select. ----
103
+ Every rule requiring a visible border or focus ring — E-28, E-29, P-02's
104
+ 3:1 shape floor — used to end at a call site writing `1px` or `2px` by
105
+ hand, which H-47 forbids. Two agents building different components hit
106
+ that independently and reported the same gap: no semantic name existed to
107
+ consume. These are it. */
108
+ --border-width-hairline: 1px; /* control and surface borders */
109
+ --border-width-strong: 2px; /* emphasis, selected states */
110
+
111
+ /* Focus ring geometry. NOT mode-negotiable, for the same reason
112
+ --size-touch-target is not: WCAG 2.4.11 wants a perimeter at least 2px
113
+ thick, and density is never a reason to go under an accessibility floor.
114
+ The offset keeps the ring off the control's own border so both stay
115
+ legible. */
116
+ --focus-ring-width: 2px;
117
+ --focus-ring-offset: 2px;
118
+
102
119
  /* ================= TYPE ================= */
103
120
  --font-text: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
104
121
  --font-display: var(--font-text);
@@ -59,6 +59,7 @@
59
59
  --size-control: 48px; --size-control-sm: 40px;
60
60
  --size-touch-target: 48px; --size-icon: 20px;
61
61
 
62
+ --border-width-control: var(--border-width-hairline);
62
63
  --radius-control: var(--radius-sm); --radius-surface: var(--radius-md);
63
64
  --shadow-surface: var(--shadow-none);
64
65
 
@@ -59,6 +59,7 @@
59
59
  --size-row: 36px; --size-row-compact: 32px;
60
60
  --size-touch-target: 48px; --size-icon: 16px;
61
61
 
62
+ --border-width-control: var(--border-width-hairline);
62
63
  --radius-control: var(--radius-sm); --radius-surface: var(--radius-sm);
63
64
  --shadow-surface: var(--shadow-none);
64
65
 
@@ -56,6 +56,7 @@
56
56
  --size-control: 40px; --size-control-sm: 32px; --size-row: 48px;
57
57
  --size-touch-target: 48px; --size-icon: 18px;
58
58
 
59
+ --border-width-control: var(--border-width-hairline);
59
60
  --radius-control: var(--radius-sm); --radius-surface: var(--radius-md);
60
61
  --shadow-surface: var(--shadow-none);
61
62