roast-my-design-system 4.2.3 → 4.2.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/bin/roast.mjs +1 -1
- package/package.json +1 -1
- package/skills/roast-my-design-system/scripts/diagnose/index.mjs +2 -2
- package/skills/roast-my-design-system/scripts/harvest/index.mjs +4 -4
- package/skills/roast-my-design-system/scripts/harvest/walk.mjs +13 -1
- package/skills/roast-my-design-system/scripts/lib/version.mjs +1 -1
package/bin/roast.mjs
CHANGED
|
@@ -106,7 +106,7 @@ function run(script, args, env) {
|
|
|
106
106
|
}
|
|
107
107
|
const say = (s) => { if (!asJson) console.log(s); };
|
|
108
108
|
|
|
109
|
-
say(`roast-my-design-system ${VERSION} · read-only scan, nothing leaves your machine
|
|
109
|
+
say(`roast-my-design-system ${VERSION} · read-only scan, nothing leaves your machine`);
|
|
110
110
|
// the harvest goes to a temp dir this wrapper deletes right after; tell the
|
|
111
111
|
// script so it does not print a path that will be gone seconds later
|
|
112
112
|
run('harvest/index.mjs', [target, '--out', harvestPath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roast-my-design-system",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.5",
|
|
4
4
|
"description": "Your AI can write the UI. This makes sure it writes your UI. A deterministic scanner counts every colour, spacing value and duplicate component, scores you 0-100 against 34 public repos, scopes the scan with .roastignore, injects agent rules with --apply.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design-system",
|
|
@@ -1324,5 +1324,5 @@ if (summaryPath) {
|
|
|
1324
1324
|
|
|
1325
1325
|
console.log(`✓ Diagnosis for ${repoName}`);
|
|
1326
1326
|
if (healthScore !== null) console.log(` score: ${healthScore}/100`);
|
|
1327
|
-
console.log(
|
|
1328
|
-
console.log(` → ${outPath}`);
|
|
1327
|
+
console.log(`\n Verdict: ${verdict}`);
|
|
1328
|
+
console.log(` Your free report is here → ${outPath}`);
|
|
@@ -171,8 +171,8 @@ const top = (list, n = 5) => list.some((e) => e.count > 1)
|
|
|
171
171
|
? ` top: ${list.slice(0, n).map((e) => `${showVal(e.value)} ×${e.count}`).join(', ')}`
|
|
172
172
|
: (list.length ? ', none repeated' : '');
|
|
173
173
|
|
|
174
|
-
console.log(
|
|
175
|
-
console.log(` framework: ${profile.framework}${profile.typescript ? ' + TS' : ''} design system: ${profile.designSystem.kind}${profile.designSystem.name ? ` (${profile.designSystem.name})` : ''} styling: ${profile.stylingDeps.join(', ') || 'none detected'}`);
|
|
174
|
+
console.log(`Harvest: ${profile.name ?? target}`);
|
|
175
|
+
console.log(` → framework: ${profile.framework}${profile.typescript ? ' + TS' : ''} design system: ${profile.designSystem.kind}${profile.designSystem.name ? ` (${profile.designSystem.name})` : ''} styling: ${profile.stylingDeps.join(', ') || 'none detected'}`);
|
|
176
176
|
console.log(` files: ${files.code.length} code, ${files.styles.length} style`);
|
|
177
177
|
if (exclusions.patterns.length) {
|
|
178
178
|
// Same voice as the report header: source named once, slashes on folders,
|
|
@@ -197,7 +197,7 @@ console.log(` context files: ${context.map((c) => c.file).join(', ') || 'none'}
|
|
|
197
197
|
// The npx wrapper writes the harvest to a temp dir it deletes right after;
|
|
198
198
|
// pointing the user at a path that will not exist is noise there.
|
|
199
199
|
if (process.env.ROAST_EPHEMERAL_OUT === '1') {
|
|
200
|
-
console.log(`\n scanned in ${harvest.tookMs}ms
|
|
200
|
+
console.log(`\n scanned in ${harvest.tookMs}ms`);
|
|
201
201
|
} else {
|
|
202
|
-
console.log(`\n → ${outPath} (${harvest.tookMs}ms)
|
|
202
|
+
console.log(`\n → ${outPath} (${harvest.tookMs}ms)`);
|
|
203
203
|
}
|
|
@@ -160,10 +160,19 @@ export function profileRepo(root, files) {
|
|
|
160
160
|
const knownLib = KNOWN_LIBRARIES.find((d) => deps[d.pkg]);
|
|
161
161
|
const homegrown = files.code.filter((f) => /(^|\/)components\//.test(f) && !/\/components\/ui\//.test(f) && /\.(tsx|jsx)$/.test(f));
|
|
162
162
|
|
|
163
|
+
// A design system does not have to arrive through npm. A stylesheet defining
|
|
164
|
+
// a real set of CSS custom properties IS one — arguably the purest form —
|
|
165
|
+
// and calling it "none" undersells exactly the discipline the ideal asks for.
|
|
166
|
+
const tokenDefs = files.styles.slice(0, 8).reduce((sum, f) => {
|
|
167
|
+
const css = read(join(root, f));
|
|
168
|
+
return sum + (css ? (css.match(/--[A-Za-z0-9_-]+\s*:/g) ?? []).length : 0);
|
|
169
|
+
}, 0);
|
|
170
|
+
|
|
163
171
|
let designSystem;
|
|
164
172
|
if (isShadcn) designSystem = { kind: 'shadcn', name: 'shadcn/ui', confidence: 'high' };
|
|
165
173
|
else if (knownLib) designSystem = { kind: 'library', name: knownLib.name, pkg: knownLib.pkg, confidence: 'high' };
|
|
166
174
|
else if (homegrown.length >= 3) designSystem = { kind: 'custom', name: 'custom (unrecognized)', confidence: 'low' };
|
|
175
|
+
else if (tokenDefs >= 5) designSystem = { kind: 'custom', name: 'CSS tokens', confidence: 'medium' };
|
|
167
176
|
else designSystem = { kind: 'none', confidence: 'high' };
|
|
168
177
|
|
|
169
178
|
// Import alias from tsconfig paths or components.json
|
|
@@ -175,7 +184,10 @@ export function profileRepo(root, files) {
|
|
|
175
184
|
if (key) alias = key.replace('/*', '');
|
|
176
185
|
}
|
|
177
186
|
|
|
178
|
-
|
|
187
|
+
// No toolchain in package.json does not mean no styling: if the walk found
|
|
188
|
+
// real stylesheets, plain CSS is what is there — say so, not "none detected".
|
|
189
|
+
let styling = STYLING_DEPS.filter((s) => deps[s.pkg]).map((s) => s.label);
|
|
190
|
+
if (!styling.length && files.styles.length) styling = ['plain CSS'];
|
|
179
191
|
|
|
180
192
|
// The git remote is a far better identity than package.json's name field
|
|
181
193
|
// ("chatbot" vs "vercel/ai-chatbot"). Parsed from .git/config, no git exec.
|