onsystem 0.11.1 → 0.12.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/dist/cli.js +169 -21
- package/dist/{design-system-D7ppJYbd.js → design-system-jpX0zFNy.js} +17 -4
- package/dist/eslint-worker.js +2 -2
- package/dist/eslint.js +1 -1
- package/dist/index.js +2 -2
- package/dist/{stdio-c3Y34to3.js → stdio-DKayvYuq.js} +2 -2
- package/dist/{workspace-DUgzMLGs.js → workspace-DH5RWgR2.js} +3 -2
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as DEFAULT_TOKENS, A as unrecordedRules, At as relativePath, B as statusKinds, C as countBaseline, D as pruneBaseline, Dt as isInside, E as onLines, Et as SCRIPT_FILE, It as unique, J as ConfigError, L as toDesignMd, M as writeBaseline, O as readBaseline, Ot as matchesGlob, Pt as plural, R as toDtcg, Rt as readProjectConfig, S as applyBaseline, St as isDesignSystemName, T as goneFiles, Y as DEFAULT_DOCS, _ as formatDiagnostics, _t as PACKAGE_FIELD, b as BASELINE_FILE, bt as detectProject, c as silentLogger, et as FALLBACK_TOKENS, g as escapeData, gt as notReadYet, h as uncheckedNotice, ht as libraryTitle, i as componentFiles, j as updateBaseline, jt as toPosix, k as rulesRun, l as stderrLogger, o as loadDesignSystem, ot as excludedBy, q as CONFIG_FILES, rt as RULE_IDS, s as tokenFiles, tt as LEGACY_CONFIG_FILES, ut as rulesFor, v as NAME, w as findMoves, x as LEGACY_BASELINE_FILE, y as VERSION, yt as declaredConfig } from "./design-system-
|
|
3
|
-
import { a as notReadNotices, i as missingDependencies, o as explainProject, s as librariesLeftOut, t as serveStdio } from "./stdio-
|
|
4
|
-
import { r as loadTarget } from "./workspace-
|
|
2
|
+
import { $ as DEFAULT_TOKENS, A as unrecordedRules, At as relativePath, B as statusKinds, C as countBaseline, D as pruneBaseline, Dt as isInside, E as onLines, Et as SCRIPT_FILE, It as unique, J as ConfigError, L as toDesignMd, M as writeBaseline, O as readBaseline, Ot as matchesGlob, Pt as plural, R as toDtcg, Rt as readProjectConfig, S as applyBaseline, St as isDesignSystemName, T as goneFiles, Y as DEFAULT_DOCS, _ as formatDiagnostics, _t as PACKAGE_FIELD, b as BASELINE_FILE, bt as detectProject, c as silentLogger, et as FALLBACK_TOKENS, g as escapeData, gt as notReadYet, h as uncheckedNotice, ht as libraryTitle, i as componentFiles, j as updateBaseline, jt as toPosix, k as rulesRun, l as stderrLogger, o as loadDesignSystem, ot as excludedBy, q as CONFIG_FILES, rt as RULE_IDS, s as tokenFiles, st as hasOwnConfig, tt as LEGACY_CONFIG_FILES, ut as rulesFor, v as NAME, w as findMoves, x as LEGACY_BASELINE_FILE, y as VERSION, yt as declaredConfig } from "./design-system-jpX0zFNy.js";
|
|
3
|
+
import { a as notReadNotices, i as missingDependencies, o as explainProject, s as librariesLeftOut, t as serveStdio } from "./stdio-DKayvYuq.js";
|
|
4
|
+
import { a as samePath, n as hasProjectMarker, r as loadTarget } from "./workspace-DH5RWgR2.js";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { escapePath, glob } from "tinyglobby";
|
|
8
8
|
import ts from "typescript";
|
|
9
|
+
import os from "node:os";
|
|
9
10
|
import fsp from "node:fs/promises";
|
|
10
11
|
import { spawnSync } from "node:child_process";
|
|
11
12
|
import readline from "node:readline/promises";
|
|
@@ -192,7 +193,8 @@ async function init(configOptions, options, io, runCheck) {
|
|
|
192
193
|
"--update-baseline",
|
|
193
194
|
...options.cache ? [] : ["--no-cache"]
|
|
194
195
|
], checkIo);
|
|
195
|
-
|
|
196
|
+
const shown = relativePath(io.cwd, path.join(root, "onsystem.baseline.json")) || "onsystem.baseline.json";
|
|
197
|
+
if (recorded.stdout) io.stdout(recorded.stdout.replace(` → ${BASELINE_FILE}`, ` → ${shown}`));
|
|
196
198
|
baselineWritten = fs.existsSync(path.join(root, BASELINE_FILE));
|
|
197
199
|
} else io.stdout(`No baseline written; \`${NAME} check . --update-baseline\` records one later.`);
|
|
198
200
|
}
|
|
@@ -723,19 +725,24 @@ project: each file is checked against the design system of the nearest folder
|
|
|
723
725
|
with a config, components.json or package.json, and inspect lists every project.
|
|
724
726
|
|
|
725
727
|
Options
|
|
726
|
-
--root <dir> Project root (default: the config file's directory, or
|
|
727
|
-
|
|
728
|
+
--root <dir> Project root (default: the config file's directory, or
|
|
729
|
+
cwd; from a folder with no config, components.json,
|
|
730
|
+
package.json or project.json, the nearest folder above
|
|
731
|
+
it with one)
|
|
732
|
+
--config <file> Config file (default: onsystem.config.{json,ts,mts,js,mjs})
|
|
728
733
|
--components <glob> Component sources, repeatable (default: found through
|
|
729
734
|
components.json or a workspace package, else
|
|
730
735
|
components/ui/**/*.{tsx,jsx} and src/components/ui/...)
|
|
731
|
-
--tokens <file> Token file (DTCG .json or
|
|
736
|
+
--tokens <file> Token file (DTCG .json, CSS or DESIGN.md), repeatable
|
|
732
737
|
--docs <glob> Component docs (Markdown/MDX), repeatable
|
|
733
738
|
--no-cache Ignore the on-disk extraction cache
|
|
734
739
|
--no-watch serve: do not reload when files change
|
|
735
740
|
--format <format> check: pretty | json | github | sarif (default: pretty);
|
|
741
|
+
inspect: pretty | json (default: pretty);
|
|
736
742
|
export: dtcg | design-md
|
|
737
743
|
--out <file> export: write to this file instead of stdout
|
|
738
744
|
--max-warnings <n> check: exit 1 when there are more than n warnings
|
|
745
|
+
(--max-warnings=-1: no limit)
|
|
739
746
|
--update-baseline check: record the current findings as accepted, and exit 0
|
|
740
747
|
--prune-baseline check: drop baseline entries that no longer occur, and
|
|
741
748
|
accept nothing new
|
|
@@ -803,6 +810,7 @@ async function main(argv, io = defaultIo) {
|
|
|
803
810
|
args: argv,
|
|
804
811
|
allowPositionals: true,
|
|
805
812
|
allowNegative: true,
|
|
813
|
+
tokens: true,
|
|
806
814
|
options: {
|
|
807
815
|
root: { type: "string" },
|
|
808
816
|
config: { type: "string" },
|
|
@@ -886,7 +894,7 @@ async function main(argv, io = defaultIo) {
|
|
|
886
894
|
io.stderr(`${error.message}\n\nRun ${NAME} --help for usage.`);
|
|
887
895
|
return 2;
|
|
888
896
|
}
|
|
889
|
-
const { values, positionals } = parsed;
|
|
897
|
+
const { values, positionals, tokens } = parsed;
|
|
890
898
|
if (values.help) {
|
|
891
899
|
io.stdout(HELP);
|
|
892
900
|
return 0;
|
|
@@ -900,11 +908,34 @@ async function main(argv, io = defaultIo) {
|
|
|
900
908
|
io.stdout(HELP);
|
|
901
909
|
return 0;
|
|
902
910
|
}
|
|
911
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
912
|
+
for (const token of tokens) {
|
|
913
|
+
if (token.kind !== "option") continue;
|
|
914
|
+
const commands = COMMAND_OPTIONS[token.name];
|
|
915
|
+
if (!commands || !isCommand(command) || commands.includes(command)) continue;
|
|
916
|
+
const owners = listOf(commands, commands.length);
|
|
917
|
+
if (command !== "serve") {
|
|
918
|
+
io.stderr(`${command}: ${token.rawName} is an option of ${owners} only. Run ${NAME} --help for usage.`);
|
|
919
|
+
return 2;
|
|
920
|
+
}
|
|
921
|
+
if (!ignored.has(token.rawName)) {
|
|
922
|
+
ignored.add(token.rawName);
|
|
923
|
+
io.stderr(`serve: ${token.rawName} is an option of ${owners} only, so it is ignored.`);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
903
926
|
let root = values.root;
|
|
904
927
|
if (root !== void 0 && /\$\{[^}]*\}/.test(root)) {
|
|
905
928
|
io.stderr(`--root "${root}" holds a variable the client did not expand; using the working directory instead${command === "serve" ? ", or the client's roots when it holds no project" : ""}.`);
|
|
906
929
|
root = void 0;
|
|
907
930
|
}
|
|
931
|
+
const given = [
|
|
932
|
+
values.config,
|
|
933
|
+
values.components,
|
|
934
|
+
values.tokens,
|
|
935
|
+
values.docs
|
|
936
|
+
];
|
|
937
|
+
let walkedUp;
|
|
938
|
+
if (root === void 0 && command !== "serve" && given.every((v) => v === void 0)) root = walkedUp = enclosingProject(io.cwd);
|
|
908
939
|
const configOptions = {
|
|
909
940
|
cwd: io.cwd,
|
|
910
941
|
root,
|
|
@@ -926,7 +957,7 @@ async function main(argv, io = defaultIo) {
|
|
|
926
957
|
...io.transport ? { transport: io.transport } : {}
|
|
927
958
|
});
|
|
928
959
|
return 0;
|
|
929
|
-
case "check": return await check(rest, configOptions, values, io);
|
|
960
|
+
case "check": return await check(rest, configOptions, values, io, walkedUp);
|
|
930
961
|
case "inspect": return await inspect(configOptions, values, io);
|
|
931
962
|
case "export": return await exportTokens(configOptions, values, io);
|
|
932
963
|
case "init": return await init(configOptions, {
|
|
@@ -956,11 +987,79 @@ async function main(argv, io = defaultIo) {
|
|
|
956
987
|
io.stderr(error.message);
|
|
957
988
|
return 2;
|
|
958
989
|
}
|
|
990
|
+
if (command === "init" && error.name === "AbortError") {
|
|
991
|
+
io.stderr("\ninit: cancelled; nothing after that question was done.");
|
|
992
|
+
return 130;
|
|
993
|
+
}
|
|
959
994
|
io.stderr(error.stack ?? String(error));
|
|
960
995
|
return 2;
|
|
961
996
|
}
|
|
962
997
|
}
|
|
963
|
-
|
|
998
|
+
const COMMANDS = [
|
|
999
|
+
"serve",
|
|
1000
|
+
"check",
|
|
1001
|
+
"inspect",
|
|
1002
|
+
"export",
|
|
1003
|
+
"init"
|
|
1004
|
+
];
|
|
1005
|
+
function isCommand(name) {
|
|
1006
|
+
return COMMANDS.includes(name);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* The options that `--help` gives to some commands only (`check:` in its text), by parser name.
|
|
1010
|
+
* The others apply to every command. test/cli-docs.test.ts holds the two together.
|
|
1011
|
+
*/
|
|
1012
|
+
const COMMAND_OPTIONS = {
|
|
1013
|
+
watch: ["serve"],
|
|
1014
|
+
format: [
|
|
1015
|
+
"check",
|
|
1016
|
+
"inspect",
|
|
1017
|
+
"export"
|
|
1018
|
+
],
|
|
1019
|
+
out: ["export"],
|
|
1020
|
+
"max-warnings": ["check"],
|
|
1021
|
+
"update-baseline": ["check"],
|
|
1022
|
+
"prune-baseline": ["check"],
|
|
1023
|
+
baseline: ["check"],
|
|
1024
|
+
"ignore-baseline": ["check"],
|
|
1025
|
+
"include-design-system": ["check"],
|
|
1026
|
+
"include-tests": ["check"],
|
|
1027
|
+
"skip-excluded": ["check"],
|
|
1028
|
+
"quiet-without-design-system": ["check"],
|
|
1029
|
+
"require-design-system": ["check"],
|
|
1030
|
+
explain: ["inspect"],
|
|
1031
|
+
yes: ["init"],
|
|
1032
|
+
force: ["init"]
|
|
1033
|
+
};
|
|
1034
|
+
/**
|
|
1035
|
+
* The project around `cwd` when `cwd` is none: the nearest folder above it with a config, a
|
|
1036
|
+
* components.json, a package.json or a project.json, relative to `cwd` (`../..`), as a command
|
|
1037
|
+
* that names it with `--root` would. Undefined when `cwd` has one of those or a baseline (a run
|
|
1038
|
+
* from there recorded it), when `cwd` is the home folder, or when no folder up to the home folder
|
|
1039
|
+
* or the filesystem root, neither of which counts, has one. Undefined, too, when `cwd` has a
|
|
1040
|
+
* folder zero config reads components from (a design system with no package.json) and the
|
|
1041
|
+
* project above would not read it: `cwd` is not the project's `src` or `app` folder, which hold
|
|
1042
|
+
* its own code, and the project has no components.json or config to say where its components are.
|
|
1043
|
+
*/
|
|
1044
|
+
function enclosingProject(cwd) {
|
|
1045
|
+
const has = (dir, name) => fs.existsSync(path.join(dir, name));
|
|
1046
|
+
if (hasProjectMarker(cwd) || ["onsystem.baseline.json", "design-system-mcp.baseline.json"].some((f) => has(cwd, f))) return;
|
|
1047
|
+
const home = os.homedir();
|
|
1048
|
+
const never = (dir) => samePath(dir, home) || dir === path.dirname(dir);
|
|
1049
|
+
if (samePath(cwd, home)) return void 0;
|
|
1050
|
+
let above = path.dirname(cwd);
|
|
1051
|
+
while (!never(above) && !hasProjectMarker(above)) above = path.dirname(above);
|
|
1052
|
+
if (never(above)) return void 0;
|
|
1053
|
+
const ownComponents = ["components/ui", "src/components/ui"].some((f) => has(cwd, f));
|
|
1054
|
+
const readAbove = ["src", "app"].some((name) => samePath(cwd, path.join(above, name))) || has(above, "components.json") || hasOwnConfig(above);
|
|
1055
|
+
if (ownComponents && !readAbove) return void 0;
|
|
1056
|
+
return path.relative(cwd, above);
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* `walkedUp`: the root, relative to the working directory, when the run took the project around
|
|
1060
|
+
* the working directory as its root (`enclosingProject`).
|
|
1061
|
+
*/
|
|
1062
|
+
async function check(patterns, configOptions, values, io, walkedUp) {
|
|
964
1063
|
if (values["quiet-without-design-system"] && values["require-design-system"]) {
|
|
965
1064
|
io.stderr("check: pass --quiet-without-design-system or --require-design-system, not both");
|
|
966
1065
|
return 2;
|
|
@@ -983,15 +1082,22 @@ async function check(patterns, configOptions, values, io) {
|
|
|
983
1082
|
io.stderr(`check: unknown --format "${format}" (pretty, json, github, sarif)`);
|
|
984
1083
|
return 2;
|
|
985
1084
|
}
|
|
986
|
-
const
|
|
987
|
-
if (
|
|
988
|
-
io.stderr(
|
|
1085
|
+
const given = values["max-warnings"];
|
|
1086
|
+
if (given !== void 0 && !/^-?\d+$/.test(given)) {
|
|
1087
|
+
io.stderr(`check: --max-warnings expects a whole number (--max-warnings=-1 for no limit), not "${given}"`);
|
|
989
1088
|
return 2;
|
|
990
1089
|
}
|
|
1090
|
+
const maxWarnings = given === void 0 || Number(given) < 0 ? void 0 : Number(given);
|
|
1091
|
+
const where = walkedUp === void 0 ? void 0 : toPosix(walkedUp);
|
|
1092
|
+
if (where !== void 0 && !values["quiet-without-design-system"]) {
|
|
1093
|
+
const text = `Checking the project in ${where}`;
|
|
1094
|
+
if (format === "pretty") io.stdout(text);
|
|
1095
|
+
else io.stderr(text);
|
|
1096
|
+
}
|
|
991
1097
|
const target = await loadTarget(configOptions);
|
|
992
1098
|
warnDeprecated(target.config.deprecations, format, io);
|
|
993
1099
|
warnDeprecated(configWarnings(target), format, io);
|
|
994
|
-
const selection = target.workspace ? await selectInWorkspace(target.workspace, patterns, values, format, io) : await selectInProject(target.config, patterns, values, format, io);
|
|
1100
|
+
const selection = target.workspace ? await selectInWorkspace(target.workspace, patterns, values, format, io) : await selectInProject(target.config, patterns, values, format, io, where);
|
|
995
1101
|
if (typeof selection === "number") return selection;
|
|
996
1102
|
const command = (flag) => checkCommand(patterns, configOptions, values, flag);
|
|
997
1103
|
if ("noMatch" in selection) {
|
|
@@ -1302,8 +1408,11 @@ function jsxNotice(selection, cwd, command) {
|
|
|
1302
1408
|
const check = command(selection.jsxGlobs.map(shellQuote).join(" "));
|
|
1303
1409
|
return files.length === 1 ? `${files[0] ?? ""} has JSX, but folders are checked for .tsx and .jsx files, so it was not checked. Name it to check it: \`${check}\`.` : `${files.length.toLocaleString("en-US")} .js files have JSX (${listOf(files)}), but folders are checked for .tsx and .jsx files, so they were not checked. Name them to check them: \`${check}\`.`;
|
|
1304
1410
|
}
|
|
1305
|
-
/**
|
|
1306
|
-
|
|
1411
|
+
/**
|
|
1412
|
+
* One project: the root's config and design system for every file. `where`: the root as the
|
|
1413
|
+
* notices name it, when the run is not from there.
|
|
1414
|
+
*/
|
|
1415
|
+
async function selectInProject(config, patterns, values, format, io, where) {
|
|
1307
1416
|
const ds = await loadDesignSystem(config, {
|
|
1308
1417
|
cache: values.cache,
|
|
1309
1418
|
logger: silentLogger
|
|
@@ -1344,7 +1453,7 @@ async function selectInProject(config, patterns, values, format, io) {
|
|
|
1344
1453
|
printNoResults(format, io);
|
|
1345
1454
|
return 0;
|
|
1346
1455
|
}
|
|
1347
|
-
const notice = ds.notice();
|
|
1456
|
+
const notice = ds.notice(where);
|
|
1348
1457
|
if (notice && values["require-design-system"] && !ds.hasDesignSystem()) {
|
|
1349
1458
|
io.stderr(`check --require-design-system: ${notice}`);
|
|
1350
1459
|
for (const text of notReadNotices([{ ds }])) io.stderr(text);
|
|
@@ -1393,6 +1502,7 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
|
|
|
1393
1502
|
if (!found) throw new Error(`No project for ${file}`);
|
|
1394
1503
|
return found;
|
|
1395
1504
|
};
|
|
1505
|
+
const shown = (p) => relativePath(io.cwd, p.root) || ".";
|
|
1396
1506
|
const designSystems = /* @__PURE__ */ new Map();
|
|
1397
1507
|
const load = (p) => {
|
|
1398
1508
|
let ds = designSystems.get(p.root);
|
|
@@ -1463,7 +1573,13 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
|
|
|
1463
1573
|
}
|
|
1464
1574
|
if (!complete) {
|
|
1465
1575
|
const packages = workspace.projects.length + workspace.others.length;
|
|
1466
|
-
|
|
1576
|
+
const lacking = /* @__PURE__ */ new Map();
|
|
1577
|
+
for (const p of workspace.projects) {
|
|
1578
|
+
const gap = missingFrom(await load(p));
|
|
1579
|
+
if (gap) lacking.set(gap.what, [...lacking.get(gap.what) ?? [], shown(p)]);
|
|
1580
|
+
}
|
|
1581
|
+
const why = [...lacking].map(([what, dirs]) => `; ${what} in ${listOf(dirs)}`).join("");
|
|
1582
|
+
io.stderr(`check --require-design-system: no workspace package has a design system with components and color tokens (${plural(packages, "package")} looked at${why}). See ${DOCS}/troubleshooting`);
|
|
1467
1583
|
return 2;
|
|
1468
1584
|
}
|
|
1469
1585
|
}
|
|
@@ -1481,7 +1597,7 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
|
|
|
1481
1597
|
ds,
|
|
1482
1598
|
dirs: []
|
|
1483
1599
|
};
|
|
1484
|
-
gap.dirs.push(p
|
|
1600
|
+
gap.dirs.push(shown(p));
|
|
1485
1601
|
gaps.set(notice, gap);
|
|
1486
1602
|
}
|
|
1487
1603
|
const notices = [...gaps.values()].map(({ ds, dirs }) => ds.notice(listOf(dirs)) ?? "");
|
|
@@ -1489,7 +1605,7 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
|
|
|
1489
1605
|
const ds = loaded.get(p.root);
|
|
1490
1606
|
return ds ? [{
|
|
1491
1607
|
ds,
|
|
1492
|
-
dir: p
|
|
1608
|
+
dir: shown(p)
|
|
1493
1609
|
}] : [];
|
|
1494
1610
|
});
|
|
1495
1611
|
notices.push(...notReadNotices(checkedProjects));
|
|
@@ -1514,6 +1630,11 @@ function listOf(items, max = 3) {
|
|
|
1514
1630
|
return `${items.slice(0, max).join(", ")} and ${items.length - max} more`;
|
|
1515
1631
|
}
|
|
1516
1632
|
async function inspect(configOptions, values, io) {
|
|
1633
|
+
const format = values.format ?? "pretty";
|
|
1634
|
+
if (!["pretty", "json"].includes(format)) {
|
|
1635
|
+
io.stderr(`inspect: unknown --format "${format}" (pretty, json)`);
|
|
1636
|
+
return 2;
|
|
1637
|
+
}
|
|
1517
1638
|
const target = await loadTarget(configOptions);
|
|
1518
1639
|
const { config } = target;
|
|
1519
1640
|
warnDeprecated(config.deprecations, "pretty", io);
|
|
@@ -1552,6 +1673,8 @@ async function inspect(configOptions, values, io) {
|
|
|
1552
1673
|
}
|
|
1553
1674
|
lines.push("", `Tokens (${model.tokens.length})`);
|
|
1554
1675
|
for (const [category, n] of tokenCounts(model)) lines.push(` ${category.padEnd(18)} ${n}`);
|
|
1676
|
+
const gap = missingFrom(ds);
|
|
1677
|
+
if (gap) lines.push("", `${gap.found}: check will not run ${gap.rules}. See ${DOCS}/configuration`);
|
|
1555
1678
|
if (model.warnings.length) {
|
|
1556
1679
|
lines.push("", "Warnings");
|
|
1557
1680
|
for (const warning of model.warnings) lines.push(` ${warning}`);
|
|
@@ -1563,6 +1686,30 @@ async function inspect(configOptions, values, io) {
|
|
|
1563
1686
|
return 0;
|
|
1564
1687
|
}
|
|
1565
1688
|
/**
|
|
1689
|
+
* What a design system lacks for `check` to run all its rules, as `DesignSystem.notice()` says
|
|
1690
|
+
* after a check: components, color tokens or both. Undefined when it has both.
|
|
1691
|
+
*/
|
|
1692
|
+
function missingFrom(ds) {
|
|
1693
|
+
const components = ds.model.components.length > 0;
|
|
1694
|
+
const colors = ds.tokenIndex.has("color");
|
|
1695
|
+
if (components && colors) return void 0;
|
|
1696
|
+
if (components) return {
|
|
1697
|
+
what: "no color tokens",
|
|
1698
|
+
found: "No color tokens found",
|
|
1699
|
+
rules: "no-hardcoded-color"
|
|
1700
|
+
};
|
|
1701
|
+
if (colors) return {
|
|
1702
|
+
what: "no components",
|
|
1703
|
+
found: "No design-system components found",
|
|
1704
|
+
rules: "the component rules"
|
|
1705
|
+
};
|
|
1706
|
+
return {
|
|
1707
|
+
what: "no components or color tokens",
|
|
1708
|
+
found: "No design system found (no components or color tokens)",
|
|
1709
|
+
rules: "the component rules or no-hardcoded-color"
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
/**
|
|
1566
1713
|
* `MUI (@mui/material 9.4.0): 149 components from its type declarations`, per library the
|
|
1567
1714
|
* project depends on, including those the config's `libraries` leaves out.
|
|
1568
1715
|
*/
|
|
@@ -1664,8 +1811,9 @@ async function inspectWorkspace(workspace, values, io) {
|
|
|
1664
1811
|
const { model } = ds;
|
|
1665
1812
|
const roots = ds.roots();
|
|
1666
1813
|
const tokens = [...tokenCounts(model)].map(([category, n]) => `${category} ${n}`);
|
|
1814
|
+
const gap = missingFrom(ds);
|
|
1667
1815
|
const own = project.config.configFile && (project.config.configFile !== workspace.configFile || project.config.designSystemPackage) ? `${displayPath(workspace.root, project.config.configFile)}${declaredBy(project.config, (f) => displayPath(workspace.root, f))}` : void 0;
|
|
1668
|
-
lines.push("", `${project.dir}${project.name ? ` (${project.name})` : ""}`, ...own ? [` config ${own}`] : [], ...project.config.detected ? [` detected ${project.config.detected}`] : [], ...describeLibraries(project.config, model, io.cwd).map((line) => ` library ${line}`), ` files ${plural(model.stats.files.components, "component file")}, ${plural(model.stats.files.tokens, "token file")}, ${plural(model.stats.files.docs, "doc")}`, ` components ${roots.length} + ${ds.components.length - roots.length} parts${roots.length ? `: ${listNames(roots.map((c) => c.name))}` : ""}`, ` tokens ${tokens.length ? tokens.join(", ") : "none"}`, ...model.warnings.length ? [` warnings ${model.warnings.length}: ${model.warnings[0] ?? ""}`] : []);
|
|
1816
|
+
lines.push("", `${project.dir}${project.name ? ` (${project.name})` : ""}`, ...own ? [` config ${own}`] : [], ...project.config.detected ? [` detected ${project.config.detected}`] : [], ...describeLibraries(project.config, model, io.cwd).map((line) => ` library ${line}`), ` files ${plural(model.stats.files.components, "component file")}, ${plural(model.stats.files.tokens, "token file")}, ${plural(model.stats.files.docs, "doc")}`, ` components ${roots.length} + ${ds.components.length - roots.length} parts${roots.length ? `: ${listNames(roots.map((c) => c.name))}` : ""}`, ` tokens ${tokens.length ? tokens.join(", ") : "none"}`, ...gap ? [` missing ${gap.what.replace(/^no /, "")}: check will not run ${gap.rules}`] : [], ...model.warnings.length ? [` warnings ${model.warnings.length}: ${model.warnings[0] ?? ""}`] : []);
|
|
1669
1817
|
}
|
|
1670
1818
|
if (!loaded.length) lines.push("", `No workspace package has a design system that zero config finds. See ${DOCS}/troubleshooting`);
|
|
1671
1819
|
if (workspace.others.length) lines.push("", `Without a design system (${workspace.others.length}): ${listNames(workspace.others)}`);
|
|
@@ -12346,7 +12346,7 @@ function isObject(value) {
|
|
|
12346
12346
|
// package.json
|
|
12347
12347
|
var name = "onsystem";
|
|
12348
12348
|
// src/version.ts
|
|
12349
|
-
const VERSION = "0.
|
|
12349
|
+
const VERSION = "0.12.0";
|
|
12350
12350
|
const NAME = name;
|
|
12351
12351
|
// src/lint/sarif.ts
|
|
12352
12352
|
const SCHEMA = "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json";
|
|
@@ -12481,7 +12481,7 @@ function formatDiagnostics(results, format, options = {}) {
|
|
|
12481
12481
|
const lines = results.flatMap((result) => {
|
|
12482
12482
|
const file = options.uri ? options.uri(result.file) : result.file;
|
|
12483
12483
|
return result.diagnostics.map((d) => {
|
|
12484
|
-
return `::${d.severity === "error" ? "error" : "warning"} ${`file=${escapeProperty(file)},line=${d.line},col=${d.column},endLine=${d.endLine},endColumn=${d.endColumn},title=${escapeProperty(d.ruleId)}`}::${escapeData(d.message)}`;
|
|
12484
|
+
return `::${d.severity === "error" ? "error" : "warning"} ${`file=${escapeProperty(file)},line=${d.line},col=${d.column},endLine=${d.endLine},endColumn=${d.endColumn},title=${escapeProperty(`onsystem: ${d.ruleId}`)}`}::${escapeData(d.message)}`;
|
|
12485
12485
|
});
|
|
12486
12486
|
});
|
|
12487
12487
|
if (fixedHint) lines.push(`::notice title=onsystem baseline::${escapeData(fixedHint)}`);
|
|
@@ -12992,7 +12992,7 @@ const STEMMED_SYNONYMS = new Map(Object.entries({
|
|
|
12992
12992
|
surface: ["card"],
|
|
12993
12993
|
section: ["card"],
|
|
12994
12994
|
dropdown: ["select", "menu"],
|
|
12995
|
-
picker: ["select"],
|
|
12995
|
+
picker: ["select", "calendar"],
|
|
12996
12996
|
combobox: ["select"],
|
|
12997
12997
|
notification: ["toast", "alert"],
|
|
12998
12998
|
snackbar: ["toast"],
|
|
@@ -13002,7 +13002,20 @@ const STEMMED_SYNONYMS = new Map(Object.entries({
|
|
|
13002
13002
|
loader: ["spinner", "skeleton"],
|
|
13003
13003
|
loading: ["spinner", "skeleton"],
|
|
13004
13004
|
divider: ["separator"],
|
|
13005
|
-
|
|
13005
|
+
profile: ["avatar"],
|
|
13006
|
+
initials: ["avatar"],
|
|
13007
|
+
headshot: ["avatar"],
|
|
13008
|
+
gravatar: ["avatar"],
|
|
13009
|
+
offcanvas: ["sheet"],
|
|
13010
|
+
slideover: ["sheet"],
|
|
13011
|
+
expandable: ["accordion"],
|
|
13012
|
+
faq: ["accordion"],
|
|
13013
|
+
multiline: ["textarea"],
|
|
13014
|
+
range: ["slider"],
|
|
13015
|
+
date: ["calendar"],
|
|
13016
|
+
schedule: ["calendar"],
|
|
13017
|
+
palette: ["command"],
|
|
13018
|
+
cmdk: ["command"]
|
|
13006
13019
|
}).map(([word, related]) => [stemmer(word), related.map((r) => stemmer(r))]));
|
|
13007
13020
|
/** Query terms plus synonyms; synonyms carry a lower weight. */
|
|
13008
13021
|
function expandQuery(query) {
|
package/dist/eslint-worker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { At as relativePath, a as fingerprint, i as componentFiles, ot as excludedBy, r as buildModel } from "./design-system-
|
|
2
|
-
import { r as loadTarget } from "./workspace-
|
|
1
|
+
import { At as relativePath, a as fingerprint, i as componentFiles, ot as excludedBy, r as buildModel } from "./design-system-jpX0zFNy.js";
|
|
2
|
+
import { r as loadTarget } from "./workspace-DH5RWgR2.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
package/dist/eslint.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as relativePath, N as RULES, Q as DEFAULT_TEST_FOLDERS, X as DEFAULT_SEVERITY, Z as DEFAULT_TEST_EXCLUDE, m as checkSource, rt as RULE_IDS, t as DesignSystem, ut as rulesFor, v as NAME, y as VERSION } from "./design-system-
|
|
1
|
+
import { At as relativePath, N as RULES, Q as DEFAULT_TEST_FOLDERS, X as DEFAULT_SEVERITY, Z as DEFAULT_TEST_EXCLUDE, m as checkSource, rt as RULE_IDS, t as DesignSystem, ut as rulesFor, v as NAME, y as VERSION } from "./design-system-jpX0zFNy.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { MessageChannel, Worker, receiveMessageOnPort } from "node:worker_threads";
|
|
4
4
|
// src/eslint/bridge.ts
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { F as loadTokens, G as parseDoc, H as parseDesignMd, I as mergeTokens, K as extractComponents, L as toDesignMd, N as RULES, P as TokenIndex, R as toDtcg, U as parseCssTokens, V as parseDtcgTokens, W as attachDocs, _ as formatDiagnostics, a as fingerprint, at as defineConfig, ct as loadConfig, f as searchComponents, ft as findVariantDefinitions, it as configJsonSchema, m as checkSource, n as DesignSystemHost, o as loadDesignSystem, p as applyFixes, r as buildModel, rt as RULE_IDS, t as DesignSystem, y as VERSION } from "./design-system-
|
|
2
|
-
import { n as INSTRUCTIONS, r as createServer, t as serveStdio } from "./stdio-
|
|
1
|
+
import { F as loadTokens, G as parseDoc, H as parseDesignMd, I as mergeTokens, K as extractComponents, L as toDesignMd, N as RULES, P as TokenIndex, R as toDtcg, U as parseCssTokens, V as parseDtcgTokens, W as attachDocs, _ as formatDiagnostics, a as fingerprint, at as defineConfig, ct as loadConfig, f as searchComponents, ft as findVariantDefinitions, it as configJsonSchema, m as checkSource, n as DesignSystemHost, o as loadDesignSystem, p as applyFixes, r as buildModel, rt as RULE_IDS, t as DesignSystem, y as VERSION } from "./design-system-jpX0zFNy.js";
|
|
2
|
+
import { n as INSTRUCTIONS, r as createServer, t as serveStdio } from "./stdio-DKayvYuq.js";
|
|
3
3
|
export { DesignSystem, DesignSystemHost, INSTRUCTIONS, RULES, RULE_IDS, TokenIndex, VERSION, applyFixes, attachDocs, buildModel, checkSource, configJsonSchema, createServer, defineConfig, extractComponents, findVariantDefinitions, fingerprint, formatDiagnostics, loadConfig, loadDesignSystem, loadTokens, mergeTokens, parseCssTokens, parseDesignMd, parseDoc, parseDtcgTokens, searchComponents, serveStdio, toDesignMd, toDtcg };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { At as relativePath, Ct as isWorkspaceRoot, Dt as isInside, Et as SCRIPT_FILE, Ft as truncate, It as unique, J as ConfigError, Lt as defaultProjectConfig, Mt as closest, Nt as json, Pt as plural, X as DEFAULT_SEVERITY, bt as detectProject, ct as loadConfig, d as descriptionOf, dt as formatPx, f as searchComponents, gt as notReadYet, h as uncheckedNotice, ht as libraryTitle, kt as pathOf, mt as LIBRARY_IDS, n as DesignSystemHost, ot as excludedBy, pt as LIBRARIES, q as CONFIG_FILES, r as buildModel, rt as RULE_IDS, tt as LEGACY_CONFIG_FILES, u as buildSearchIndex, v as NAME, xt as findDesignSystemPackage, y as VERSION, z as TOKEN_CATEGORIES } from "./design-system-
|
|
2
|
-
import { i as projectDirOf, n as hasProjectMarker, r as loadTarget, t as findProjectRoot } from "./workspace-
|
|
1
|
+
import { At as relativePath, Ct as isWorkspaceRoot, Dt as isInside, Et as SCRIPT_FILE, Ft as truncate, It as unique, J as ConfigError, Lt as defaultProjectConfig, Mt as closest, Nt as json, Pt as plural, X as DEFAULT_SEVERITY, bt as detectProject, ct as loadConfig, d as descriptionOf, dt as formatPx, f as searchComponents, gt as notReadYet, h as uncheckedNotice, ht as libraryTitle, kt as pathOf, mt as LIBRARY_IDS, n as DesignSystemHost, ot as excludedBy, pt as LIBRARIES, q as CONFIG_FILES, r as buildModel, rt as RULE_IDS, tt as LEGACY_CONFIG_FILES, u as buildSearchIndex, v as NAME, xt as findDesignSystemPackage, y as VERSION, z as TOKEN_CATEGORIES } from "./design-system-jpX0zFNy.js";
|
|
2
|
+
import { i as projectDirOf, n as hasProjectMarker, r as loadTarget, t as findProjectRoot } from "./workspace-DH5RWgR2.js";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as relativePath, Ct as isWorkspaceRoot, Dt as isInside, Tt as workspacePatterns, ct as loadConfig, i as componentFiles, lt as loadConfigWith, nt as PROJECT_MARKERS, st as hasOwnConfig, vt as PackageFinder, wt as workspacePackageDirs, xt as findDesignSystemPackage } from "./design-system-
|
|
1
|
+
import { At as relativePath, Ct as isWorkspaceRoot, Dt as isInside, Tt as workspacePatterns, ct as loadConfig, i as componentFiles, lt as loadConfigWith, nt as PROJECT_MARKERS, st as hasOwnConfig, vt as PackageFinder, wt as workspacePackageDirs, xt as findDesignSystemPackage } from "./design-system-jpX0zFNy.js";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import os from "node:os";
|
|
@@ -194,6 +194,7 @@ function findProjectRoot(target, home = os.homedir()) {
|
|
|
194
194
|
for (let up = dir; up !== path.dirname(up); up = path.dirname(up)) if (!skipped(up) && isWorkspaceRoot(up)) return up;
|
|
195
195
|
return dir;
|
|
196
196
|
}
|
|
197
|
+
/** Whether `a` and `b` are the same folder, as the platform compares paths (case-insensitive on Windows). */
|
|
197
198
|
function samePath(a, b) {
|
|
198
199
|
return path.relative(path.resolve(a), path.resolve(b)) === "";
|
|
199
200
|
}
|
|
@@ -216,4 +217,4 @@ function isDirectory(target) {
|
|
|
216
217
|
return false;
|
|
217
218
|
}
|
|
218
219
|
}
|
|
219
|
-
export { projectDirOf as i, hasProjectMarker as n, loadTarget as r, findProjectRoot as t };
|
|
220
|
+
export { samePath as a, projectDirOf as i, hasProjectMarker as n, loadTarget as r, findProjectRoot as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onsystem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"mcpName": "io.github.dgesteves/onsystem",
|
|
5
5
|
"description": "Keeps coding agents on your design system: catches palette colors, native elements and APIs your system lacks, at every edit and pull request, with the fix. Set it up once in your design-system package; every app in your monorepo gets it.",
|
|
6
6
|
"keywords": [
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
66
|
+
"@types/culori": "^4.0.1",
|
|
66
67
|
"culori": "^4.0.2",
|
|
67
68
|
"postcss": "^8.5.30",
|
|
68
69
|
"stemmer": "^2.0.1",
|
|
@@ -85,7 +86,6 @@
|
|
|
85
86
|
"@eslint/js": "^10.0.1",
|
|
86
87
|
"@modelcontextprotocol/client": "^2.3.1",
|
|
87
88
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
88
|
-
"@types/culori": "^4.0.1",
|
|
89
89
|
"@types/node": "^24.19.2",
|
|
90
90
|
"@vitest/coverage-istanbul": "^5.0.5",
|
|
91
91
|
"ajv": "^8.20.0",
|