guard-my-design-system 1.3.3 → 1.3.5
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 +96 -96
- package/package.json +2 -2
- package/src/judge.mjs +4 -1
package/README.md
CHANGED
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
## Your design system dies one pull request at a time. This makes sure it doesn't.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
It speaks in nearests, not scoldings:
|
|
7
|
+
The guard checks pull requests for design-system drift. It looks only at the
|
|
8
|
+
lines a change adds. It never judges the code that was already there. For each
|
|
9
|
+
problem it finds, it names the closest value your system already has:
|
|
12
10
|
|
|
13
11
|
> `Card.tsx:24` — new colour `#4a7be8`. Nearest token: `var(--blue-500)`, `#3b6fe0`.
|
|
14
12
|
>
|
|
@@ -20,64 +18,66 @@ It speaks in nearests, not scoldings:
|
|
|
20
18
|
>
|
|
21
19
|
> `site.css:35` — `!important`. The cascade admitting defeat; raise specificity or fix the source order.
|
|
22
20
|
|
|
23
|
-
It learns your system by scanning your
|
|
21
|
+
It learns your design system by scanning your repository with the
|
|
24
22
|
[roast-my-design-system](https://github.com/gregkozakiewicz/roast-my-design-system)
|
|
25
|
-
engine
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
write, no tokens to register. Your codebase is the rulebook.
|
|
23
|
+
engine. It reads CSS, SCSS, styled components, Lit `` css`…` `` templates and
|
|
24
|
+
Stencil styling. You do not write any config, rules or token lists. Your
|
|
25
|
+
codebase is the rulebook.
|
|
29
26
|
|
|
30
|
-
This is
|
|
27
|
+
This is the guard's comment on a real pull request:
|
|
31
28
|
|
|
32
29
|

|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
The guard posts one comment per pull request. When the author pushes fixes,
|
|
32
|
+
it updates that same comment. It never adds more comments:
|
|
36
33
|
|
|
37
34
|

|
|
38
35
|
|
|
39
36
|
## What it catches
|
|
40
37
|
|
|
41
|
-
- **A hard-coded colour where a token exists
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
-
|
|
38
|
+
- **A hard-coded colour where a token exists.** The finding names the token:
|
|
39
|
+
`var(--blue-500)`, not just a hex code. This works across colour notations:
|
|
40
|
+
a hex stray is matched to an hsl or oklch token, including shadcn's
|
|
41
|
+
bare-triplet variables.
|
|
42
|
+
- **A spacing value your codebase has never used**, with the nearest existing
|
|
43
|
+
step named.
|
|
44
|
+
- **A border radius, font size or shadow your system does not declare**, with
|
|
45
45
|
the nearest existing value named.
|
|
46
|
-
- **A typeface
|
|
47
|
-
- **`!important
|
|
48
|
-
- **Arbitrary Tailwind values**
|
|
46
|
+
- **A typeface your system does not declare.**
|
|
47
|
+
- **`!important`.**
|
|
48
|
+
- **Arbitrary Tailwind values** such as `w-[137px]` and `mt-[37px]`.
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
does it make things worse?
|
|
50
|
+
It ignores everything that was already in the codebase. It asks one question
|
|
51
|
+
of a change: does it make things worse?
|
|
53
52
|
|
|
54
53
|
## When the guard is wrong
|
|
55
54
|
|
|
56
|
-
Sometimes an off-system value is
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
Sometimes an off-system value is correct. A partner's brand colour, for
|
|
56
|
+
example. Write a comment on the line above, and the guard lets that one line
|
|
57
|
+
pass:
|
|
59
58
|
|
|
60
59
|
```css
|
|
61
60
|
/* guard-ignore-next-line — partner brand colour, agreed with design */
|
|
62
61
|
background: #e4002b;
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
The
|
|
67
|
-
|
|
68
|
-
file
|
|
64
|
+
This works in any file the guard reads: `//` in components, `/* */` in styles.
|
|
65
|
+
The comment is visible in code review. It silences exactly one line. It keeps
|
|
66
|
+
working on later pull requests that touch the same line. There is no config
|
|
67
|
+
file and there are no rule IDs.
|
|
69
68
|
|
|
70
69
|
## Why this exists
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
You cannot ask a team to clean up years of styling. You can stop new problems
|
|
72
|
+
getting in. The guard does that automatically, on every pull request.
|
|
73
|
+
|
|
74
|
+
It matters more now than ever. AI tools write a growing share of UI code, and
|
|
75
|
+
they drift off-system faster than review can catch. Rules files ask nicely;
|
|
76
|
+
the guard checks.
|
|
77
77
|
|
|
78
78
|
## On a pull request
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
Set it up once. It takes about five minutes:
|
|
81
81
|
|
|
82
82
|
```yaml
|
|
83
83
|
# .github/workflows/guard.yml
|
|
@@ -96,9 +96,10 @@ jobs:
|
|
|
96
96
|
- uses: gregkozakiewicz/guard-my-design-system@v1
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
After that
|
|
99
|
+
After that it runs on every pull request and needs no attention from you.
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
If you want the check to fail instead of commenting, turn on strict mode.
|
|
102
|
+
It is the only setting:
|
|
102
103
|
|
|
103
104
|
```yaml
|
|
104
105
|
- uses: gregkozakiewicz/guard-my-design-system@v1
|
|
@@ -106,14 +107,15 @@ Prefer a failed check over a comment? Strict mode is the one setting:
|
|
|
106
107
|
strict: true
|
|
107
108
|
```
|
|
108
109
|
|
|
109
|
-
`exclude` keeps folders out of the system scan
|
|
110
|
+
`exclude` keeps folders out of the system scan. It uses the same syntax as
|
|
111
|
+
the CLI below.
|
|
110
112
|
|
|
111
|
-
|
|
112
|
-
`uses: gregkozakiewicz/guard-my-design-system@<commit-sha>`.
|
|
113
|
+
If your team pins actions for security, use an exact commit instead of a
|
|
114
|
+
version tag: `uses: gregkozakiewicz/guard-my-design-system@<commit-sha>`.
|
|
113
115
|
|
|
114
116
|
## On your machine
|
|
115
117
|
|
|
116
|
-
|
|
118
|
+
Check your own work before you open a pull request:
|
|
117
119
|
|
|
118
120
|
```bash
|
|
119
121
|
npx guard-my-design-system@latest
|
|
@@ -121,21 +123,21 @@ npx guard-my-design-system@latest
|
|
|
121
123
|
|
|
122
124
|
| Command | What you get |
|
|
123
125
|
|---|---|
|
|
124
|
-
| <code>npx guard-my-design-system@latest</code> |
|
|
125
|
-
| <code>npx guard-my-design-system@latest <path></code> | Judge a different
|
|
126
|
-
| <code>... --base <ref></code> |
|
|
127
|
-
| `... --strict` | Exit 1
|
|
126
|
+
| <code>npx guard-my-design-system@latest</code> | The lines you have added, judged against main, in the terminal |
|
|
127
|
+
| <code>npx guard-my-design-system@latest <path></code> | Judge a different repository |
|
|
128
|
+
| <code>... --base <ref></code> | Compare against a branch other than main |
|
|
129
|
+
| `... --strict` | Exit with code 1 when there are findings, for scripts and hooks |
|
|
128
130
|
| `... --markdown` | The verdict as markdown, the same text the PR comment carries |
|
|
129
|
-
| `... --json` | Findings as JSON
|
|
130
|
-
| <code>... --exclude lab/</code> |
|
|
131
|
+
| `... --json` | Findings as JSON, for scripts and pipelines |
|
|
132
|
+
| <code>... --exclude lab/</code> | Keep folders out of the system scan (separate more with commas). A `.roastignore` file at the repository root works too |
|
|
133
|
+
| `... --version` | The version number |
|
|
131
134
|
|
|
132
|
-
|
|
135
|
+
You need Node 18 or later, and git.
|
|
133
136
|
|
|
134
137
|
## Not on GitHub?
|
|
135
138
|
|
|
136
|
-
The CLI works anywhere git works
|
|
137
|
-
GitHub
|
|
138
|
-
with two lines in `.gitlab-ci.yml`:
|
|
139
|
+
The CLI works anywhere git works. Only the comment-posting Action needs
|
|
140
|
+
GitHub. On GitLab, add this to `.gitlab-ci.yml`:
|
|
139
141
|
|
|
140
142
|
```yaml
|
|
141
143
|
guard:
|
|
@@ -147,7 +149,7 @@ guard:
|
|
|
147
149
|
- npx guard-my-design-system@latest --strict --base origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
|
148
150
|
```
|
|
149
151
|
|
|
150
|
-
Bitbucket
|
|
152
|
+
On Bitbucket, add this to `bitbucket-pipelines.yml`:
|
|
151
153
|
|
|
152
154
|
```yaml
|
|
153
155
|
pipelines:
|
|
@@ -160,59 +162,57 @@ pipelines:
|
|
|
160
162
|
- npx guard-my-design-system@latest --strict --base origin/$BITBUCKET_PR_DESTINATION_BRANCH
|
|
161
163
|
```
|
|
162
164
|
|
|
163
|
-
The verdict prints in the pipeline log and `--strict` fails the step
|
|
164
|
-
|
|
165
|
+
The verdict prints in the pipeline log, and `--strict` fails the step. The
|
|
166
|
+
updating PR comment works on GitHub only, for now.
|
|
165
167
|
|
|
166
168
|
## What makes the verdict trustworthy
|
|
167
169
|
|
|
168
170
|
- **Only added lines are checked.** The existing codebase is never judged,
|
|
169
|
-
never counted, never mentioned.
|
|
170
|
-
|
|
171
|
-
- **Deterministic, not AI sampling.** The same engine that powers
|
|
171
|
+
never counted, never mentioned.
|
|
172
|
+
- **The results are deterministic.** The same engine that powers
|
|
172
173
|
roast-my-design-system reads the diff and returns the same verdict every
|
|
173
|
-
|
|
174
|
-
- **Read-only
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
- **
|
|
181
|
-
|
|
182
|
-
and no meeting.
|
|
174
|
+
time. No AI model is involved.
|
|
175
|
+
- **Read-only. No network. No telemetry.** Everything runs on your machine or
|
|
176
|
+
your CI runner. Nothing about your code leaves it.
|
|
177
|
+
- **Fair exemptions, inherited from roast.** Email and print styling must be
|
|
178
|
+
inline, so the guard never flags it. Files that draw SVG artwork are not
|
|
179
|
+
judged on their colours. Defining a new token is extending the system, not
|
|
180
|
+
a problem.
|
|
181
|
+
- **Every finding comes with a fix.** The guard names the on-system value the
|
|
182
|
+
author probably meant, so most fixes take under a minute and no meeting.
|
|
183
183
|
|
|
184
184
|
## Honest limits
|
|
185
185
|
|
|
186
|
-
Things the guard deliberately does not do,
|
|
187
|
-
in a pull request:
|
|
188
|
-
|
|
189
|
-
- **Monorepos are judged as one
|
|
190
|
-
|
|
191
|
-
appears in `apps/web`.
|
|
192
|
-
- **Spacing is compared within one unit.**
|
|
193
|
-
`13px
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
workflow
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
GitHub-
|
|
205
|
-
- **Inside `` css`…` `` templates,
|
|
206
|
-
|
|
207
|
-
templates in full, so the system is learned correctly
|
|
208
|
-
line-level gap
|
|
186
|
+
Things the guard deliberately does not do, listed here so they never surprise
|
|
187
|
+
you in a pull request:
|
|
188
|
+
|
|
189
|
+
- **Monorepos are judged as one codebase.** The guard learns the system from
|
|
190
|
+
the whole repository. A colour that is legitimate in `packages/ui` counts
|
|
191
|
+
as known when it appears in `apps/web`. For per-package scores, use roast.
|
|
192
|
+
- **Spacing is compared within one unit.** If your scale uses rem and someone
|
|
193
|
+
adds `13px`, the guard flags it. But it will not claim `0.75rem` is the
|
|
194
|
+
nearest value to `13px`. Converting units would be a guess, and the guard
|
|
195
|
+
does not guess.
|
|
196
|
+
- **Taste is not judged.** The right token in the wrong place passes.
|
|
197
|
+
Defining a new token is never flagged. The guard checks drift, not
|
|
198
|
+
decisions.
|
|
199
|
+
- **On a pull request from a fork, the comment cannot be posted.** GitHub
|
|
200
|
+
gives the workflow a read-only token. The guard still runs, and the verdict
|
|
201
|
+
appears in the workflow log with a line explaining why. The same happens if
|
|
202
|
+
the workflow is missing `pull-requests: write`.
|
|
203
|
+
- **Not on GitHub?** Covered: GitLab and Bitbucket recipes are in
|
|
204
|
+
[Not on GitHub?](#not-on-github) above.
|
|
205
|
+
- **Inside `` css`…` `` templates, the line-by-line check catches colours but
|
|
206
|
+
not yet spacing, radii or shadows.** The whole-repository scan reads those
|
|
207
|
+
templates in full, so the system is still learned correctly. The
|
|
208
|
+
line-level gap will close with a future engine release.
|
|
209
209
|
|
|
210
210
|
## The family
|
|
211
211
|
|
|
212
212
|
[roast-my-design-system](https://github.com/gregkozakiewicz/roast-my-design-system)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
guard
|
|
213
|
+
examines your whole codebase: a health score against a 34-repo benchmark, the
|
|
214
|
+
evidence behind it, and the agent rules that keep AI-written UI on-system.
|
|
215
|
+
The guard stops new work adding to the pile.
|
|
216
216
|
|
|
217
217
|
Roast diagnoses it. Guard protects it.
|
|
218
218
|
|
|
@@ -222,7 +222,7 @@ Roast diagnoses it. Guard protects it.
|
|
|
222
222
|
|
|
223
223
|
## License
|
|
224
224
|
|
|
225
|
-
MIT.
|
|
225
|
+
MIT. You may fork, modify and redistribute the code. The copyright notice
|
|
226
226
|
travels with it.
|
|
227
227
|
|
|
228
228
|
If you build a report, summary or audit of your own from this tool's findings,
|
|
@@ -231,7 +231,7 @@ keep one line in it: *Built with
|
|
|
231
231
|
by Greg Kozakiewicz*.
|
|
232
232
|
|
|
233
233
|
**guard-my-design-system**™ and the GK mark are trademarks of Greg Kozakiewicz.
|
|
234
|
-
Forking is welcome
|
|
234
|
+
Forking is welcome. Republishing under this name is not. See
|
|
235
235
|
[brand and attribution](https://gregkozakiewicz.github.io/guard-my-design-system/brand.html).
|
|
236
236
|
|
|
237
237
|
Built and designed by <a href="https://gregkozakiewicz.com"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/gregkozakiewicz/roast-my-design-system/main/assets/gk-mark-dark.png?v=3.10.1"><img src="https://raw.githubusercontent.com/gregkozakiewicz/roast-my-design-system/main/assets/gk-mark.png?v=3.10.1" height="15" alt="GK mark"></picture> Greg Kozakiewicz</a>.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guard-my-design-system",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "Your design system dies one pull request at a time. This makes sure it doesn't. A guard that judges only the lines a change adds, against the system the repo already has, and names the on-system value the author probably meant.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"src/"
|
|
12
12
|
],
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"roast-my-design-system": "5.
|
|
14
|
+
"roast-my-design-system": "5.10.2"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
17
17
|
"design-system",
|
package/src/judge.mjs
CHANGED
|
@@ -90,7 +90,10 @@ export function judge(added, system) {
|
|
|
90
90
|
// "use var(--blue-500)", not "go hunt this hex": name a value when the
|
|
91
91
|
// system defines it as a custom property.
|
|
92
92
|
const named = (value) => {
|
|
93
|
-
|
|
93
|
+
// shadcn-style tokens are defined as bare triplets (--primary: 222.2 47.4%
|
|
94
|
+
// 11.2%) but normalised to hsl(...); try the unwrapped form too.
|
|
95
|
+
const n = system.tokenNames?.[value]
|
|
96
|
+
?? system.tokenNames?.[value.replace(/^hsla?\((.*)\)$/i, '$1')];
|
|
94
97
|
return n ? `var(${n}), ${value}` : value;
|
|
95
98
|
};
|
|
96
99
|
const faceCounts = new Map();
|