onsystem 0.11.2 → 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 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-BZoTfLBU.js";
3
- import { a as notReadNotices, i as missingDependencies, o as explainProject, s as librariesLeftOut, t as serveStdio } from "./stdio-WCDCmwJx.js";
4
- import { r as loadTarget } from "./workspace-Dx0ogKg8.js";
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
- if (recorded.stdout) io.stdout(recorded.stdout);
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,7 +725,10 @@ 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 cwd)
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)
727
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
@@ -737,6 +742,7 @@ Options
737
742
  export: dtcg | design-md
738
743
  --out <file> export: write to this file instead of stdout
739
744
  --max-warnings <n> check: exit 1 when there are more than n warnings
745
+ (--max-warnings=-1: no limit)
740
746
  --update-baseline check: record the current findings as accepted, and exit 0
741
747
  --prune-baseline check: drop baseline entries that no longer occur, and
742
748
  accept nothing new
@@ -804,6 +810,7 @@ async function main(argv, io = defaultIo) {
804
810
  args: argv,
805
811
  allowPositionals: true,
806
812
  allowNegative: true,
813
+ tokens: true,
807
814
  options: {
808
815
  root: { type: "string" },
809
816
  config: { type: "string" },
@@ -887,7 +894,7 @@ async function main(argv, io = defaultIo) {
887
894
  io.stderr(`${error.message}\n\nRun ${NAME} --help for usage.`);
888
895
  return 2;
889
896
  }
890
- const { values, positionals } = parsed;
897
+ const { values, positionals, tokens } = parsed;
891
898
  if (values.help) {
892
899
  io.stdout(HELP);
893
900
  return 0;
@@ -901,11 +908,34 @@ async function main(argv, io = defaultIo) {
901
908
  io.stdout(HELP);
902
909
  return 0;
903
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
+ }
904
926
  let root = values.root;
905
927
  if (root !== void 0 && /\$\{[^}]*\}/.test(root)) {
906
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" : ""}.`);
907
929
  root = void 0;
908
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);
909
939
  const configOptions = {
910
940
  cwd: io.cwd,
911
941
  root,
@@ -927,7 +957,7 @@ async function main(argv, io = defaultIo) {
927
957
  ...io.transport ? { transport: io.transport } : {}
928
958
  });
929
959
  return 0;
930
- case "check": return await check(rest, configOptions, values, io);
960
+ case "check": return await check(rest, configOptions, values, io, walkedUp);
931
961
  case "inspect": return await inspect(configOptions, values, io);
932
962
  case "export": return await exportTokens(configOptions, values, io);
933
963
  case "init": return await init(configOptions, {
@@ -957,11 +987,79 @@ async function main(argv, io = defaultIo) {
957
987
  io.stderr(error.message);
958
988
  return 2;
959
989
  }
990
+ if (command === "init" && error.name === "AbortError") {
991
+ io.stderr("\ninit: cancelled; nothing after that question was done.");
992
+ return 130;
993
+ }
960
994
  io.stderr(error.stack ?? String(error));
961
995
  return 2;
962
996
  }
963
997
  }
964
- async function check(patterns, configOptions, values, io) {
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) {
965
1063
  if (values["quiet-without-design-system"] && values["require-design-system"]) {
966
1064
  io.stderr("check: pass --quiet-without-design-system or --require-design-system, not both");
967
1065
  return 2;
@@ -984,15 +1082,22 @@ async function check(patterns, configOptions, values, io) {
984
1082
  io.stderr(`check: unknown --format "${format}" (pretty, json, github, sarif)`);
985
1083
  return 2;
986
1084
  }
987
- const maxWarnings = values["max-warnings"] === void 0 ? void 0 : Number(values["max-warnings"]);
988
- if (maxWarnings !== void 0 && !Number.isInteger(maxWarnings)) {
989
- io.stderr("check: --max-warnings expects an integer");
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}"`);
990
1088
  return 2;
991
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
+ }
992
1097
  const target = await loadTarget(configOptions);
993
1098
  warnDeprecated(target.config.deprecations, format, io);
994
1099
  warnDeprecated(configWarnings(target), format, io);
995
- 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);
996
1101
  if (typeof selection === "number") return selection;
997
1102
  const command = (flag) => checkCommand(patterns, configOptions, values, flag);
998
1103
  if ("noMatch" in selection) {
@@ -1303,8 +1408,11 @@ function jsxNotice(selection, cwd, command) {
1303
1408
  const check = command(selection.jsxGlobs.map(shellQuote).join(" "));
1304
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}\`.`;
1305
1410
  }
1306
- /** One project: the root's config and design system for every file. */
1307
- async function selectInProject(config, patterns, values, format, io) {
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) {
1308
1416
  const ds = await loadDesignSystem(config, {
1309
1417
  cache: values.cache,
1310
1418
  logger: silentLogger
@@ -1345,7 +1453,7 @@ async function selectInProject(config, patterns, values, format, io) {
1345
1453
  printNoResults(format, io);
1346
1454
  return 0;
1347
1455
  }
1348
- const notice = ds.notice();
1456
+ const notice = ds.notice(where);
1349
1457
  if (notice && values["require-design-system"] && !ds.hasDesignSystem()) {
1350
1458
  io.stderr(`check --require-design-system: ${notice}`);
1351
1459
  for (const text of notReadNotices([{ ds }])) io.stderr(text);
@@ -1394,6 +1502,7 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
1394
1502
  if (!found) throw new Error(`No project for ${file}`);
1395
1503
  return found;
1396
1504
  };
1505
+ const shown = (p) => relativePath(io.cwd, p.root) || ".";
1397
1506
  const designSystems = /* @__PURE__ */ new Map();
1398
1507
  const load = (p) => {
1399
1508
  let ds = designSystems.get(p.root);
@@ -1464,7 +1573,13 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
1464
1573
  }
1465
1574
  if (!complete) {
1466
1575
  const packages = workspace.projects.length + workspace.others.length;
1467
- io.stderr(`check --require-design-system: no workspace package has a design system with components and color tokens (${plural(packages, "package")} looked at). See ${DOCS}/troubleshooting`);
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`);
1468
1583
  return 2;
1469
1584
  }
1470
1585
  }
@@ -1482,7 +1597,7 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
1482
1597
  ds,
1483
1598
  dirs: []
1484
1599
  };
1485
- gap.dirs.push(p.dir);
1600
+ gap.dirs.push(shown(p));
1486
1601
  gaps.set(notice, gap);
1487
1602
  }
1488
1603
  const notices = [...gaps.values()].map(({ ds, dirs }) => ds.notice(listOf(dirs)) ?? "");
@@ -1490,7 +1605,7 @@ async function selectInWorkspace(workspace, patterns, values, format, io) {
1490
1605
  const ds = loaded.get(p.root);
1491
1606
  return ds ? [{
1492
1607
  ds,
1493
- dir: p.dir
1608
+ dir: shown(p)
1494
1609
  }] : [];
1495
1610
  });
1496
1611
  notices.push(...notReadNotices(checkedProjects));
@@ -1558,6 +1673,8 @@ async function inspect(configOptions, values, io) {
1558
1673
  }
1559
1674
  lines.push("", `Tokens (${model.tokens.length})`);
1560
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`);
1561
1678
  if (model.warnings.length) {
1562
1679
  lines.push("", "Warnings");
1563
1680
  for (const warning of model.warnings) lines.push(` ${warning}`);
@@ -1569,6 +1686,30 @@ async function inspect(configOptions, values, io) {
1569
1686
  return 0;
1570
1687
  }
1571
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
+ /**
1572
1713
  * `MUI (@mui/material 9.4.0): 149 components from its type declarations`, per library the
1573
1714
  * project depends on, including those the config's `libraries` leaves out.
1574
1715
  */
@@ -1670,8 +1811,9 @@ async function inspectWorkspace(workspace, values, io) {
1670
1811
  const { model } = ds;
1671
1812
  const roots = ds.roots();
1672
1813
  const tokens = [...tokenCounts(model)].map(([category, n]) => `${category} ${n}`);
1814
+ const gap = missingFrom(ds);
1673
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;
1674
- 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] ?? ""}`] : []);
1675
1817
  }
1676
1818
  if (!loaded.length) lines.push("", `No workspace package has a design system that zero config finds. See ${DOCS}/troubleshooting`);
1677
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.11.2";
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)}`);
@@ -1,5 +1,5 @@
1
- import { At as relativePath, a as fingerprint, i as componentFiles, ot as excludedBy, r as buildModel } from "./design-system-BZoTfLBU.js";
2
- import { r as loadTarget } from "./workspace-Dx0ogKg8.js";
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-BZoTfLBU.js";
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-BZoTfLBU.js";
2
- import { n as INSTRUCTIONS, r as createServer, t as serveStdio } from "./stdio-WCDCmwJx.js";
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-BZoTfLBU.js";
2
- import { i as projectDirOf, n as hasProjectMarker, r as loadTarget, t as findProjectRoot } from "./workspace-Dx0ogKg8.js";
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-BZoTfLBU.js";
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.11.2",
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",