onsystem 0.8.0 → 0.9.1
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 +20 -2
- package/dist/cli.js +122 -21
- package/dist/{config-kYGiD5oW.d.ts → config-B98w8bcg.d.ts} +5 -0
- package/dist/{design-system-Dmcv7eHR.js → design-system-DZm2aP1z.js} +1105 -189
- package/dist/eslint-worker.d.ts +1 -1
- package/dist/eslint-worker.js +2 -2
- package/dist/eslint.js +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.js +2 -2
- package/dist/{stdio-MTS6QAgo.js → stdio-BJvjEnKW.js} +338 -87
- package/dist/{workspace-CM1RyqZA.js → workspace-Dqu3nkYM.js} +1 -1
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Using the GitHub Action? `uses: dgesteves/onsystem@v0` checks the lines a pull r
|
|
|
20
20
|
**Also works with**
|
|
21
21
|
[](https://onsystem.vercel.app/docs/clients#codex-cli)
|
|
22
22
|
[](https://onsystem.vercel.app/docs/clients#gemini-cli)
|
|
23
|
+
[](https://onsystem.vercel.app/docs/clients#antigravity-cli-and-ide)
|
|
23
24
|
[](https://onsystem.vercel.app/docs/clients#grok-build)
|
|
24
25
|
[](https://onsystem.vercel.app/docs/clients#github-copilot-cli)
|
|
25
26
|
[](https://onsystem.vercel.app/docs/clients#claude-desktop)
|
|
@@ -29,6 +30,8 @@ Using the GitHub Action? `uses: dgesteves/onsystem@v0` checks the lines a pull r
|
|
|
29
30
|
|
|
30
31
|
**Website and docs:** [onsystem.vercel.app](https://onsystem.vercel.app), with a [playground](https://onsystem.vercel.app/playground) that checks your own code.
|
|
31
32
|
|
|
33
|
+
**Feedback wanted:** say where it breaks in the [launch feedback thread](https://github.com/dgesteves/onsystem/discussions/227), see what's next in the [roadmap](https://github.com/dgesteves/onsystem/blob/main/ROADMAP.md), or pick up a [good first issue](https://github.com/dgesteves/onsystem/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22). If onsystem is useful to you, a star helps other people find it.
|
|
34
|
+
|
|
32
35
|
<p align="center">
|
|
33
36
|
<a href="https://onsystem.vercel.app"><img src=".github/assets/demo.webp" width="100%" alt="On the website, an agent drafts a settings card, check_ui finds 11 problems with a fix each and the agent applies them. Then a real Claude Code session with the plugin, where Claude looks the components up before writing and check_ui passes. Last, the benchmark."></a>
|
|
34
37
|
</p>
|
|
@@ -83,7 +86,7 @@ After each Write or Edit of a `.tsx` or `.jsx` file, the hook runs `onsystem che
|
|
|
83
86
|
|
|
84
87
|
**Other agents.** `npx skills add dgesteves/onsystem` adds the skill to any agent with Agent Skills, and there are [plugins for Codex, GitHub Copilot CLI, VS Code and Cursor](https://onsystem.vercel.app/docs/clients#plugins-for-other-agents).
|
|
85
88
|
|
|
86
|
-
**Any MCP client.** Run `npx -y onsystem` as a stdio server. There are [configs for Claude Desktop, Codex CLI, GitHub Copilot CLI, Windsurf, JetBrains IDEs, Zed, Gemini CLI and Grok Build](https://onsystem.vercel.app/docs/clients#other-clients).
|
|
89
|
+
**Any MCP client.** Run `npx -y onsystem` as a stdio server. There are [configs for Claude Desktop, Codex CLI, GitHub Copilot CLI, Windsurf, JetBrains IDEs, Zed, Gemini CLI, Antigravity and Grok Build](https://onsystem.vercel.app/docs/clients#other-clients).
|
|
87
90
|
|
|
88
91
|
**CI.** Install it as a dev dependency, accept the findings the codebase already has once, and fail pull requests only on new ones:
|
|
89
92
|
|
|
@@ -96,7 +99,22 @@ npx onsystem check . --update-baseline # writes onsystem.baseline.json: commit
|
|
|
96
99
|
- run: npx onsystem check . --format github --require-design-system
|
|
97
100
|
```
|
|
98
101
|
|
|
99
|
-
Findings show up as annotations on the pull request, and `--require-design-system` fails the job when the design system is no longer found. [CI and baselines](https://onsystem.vercel.app/docs/ci) has the whole workflow.
|
|
102
|
+
Findings show up as annotations on the pull request, and `--require-design-system` fails the job when the design system is no longer found. [CI and baselines](https://onsystem.vercel.app/docs/ci) has the whole workflow.
|
|
103
|
+
|
|
104
|
+
**GitHub Action.** The [action](https://github.com/marketplace/actions/onsystem-design-system-check) runs the same check, honours the baseline and annotates only the lines a pull request changed. It goes after the checkout and the install, so it can read your design system:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
steps:
|
|
108
|
+
- uses: actions/checkout@v7
|
|
109
|
+
- uses: actions/setup-node@v7
|
|
110
|
+
with:
|
|
111
|
+
node-version: 24
|
|
112
|
+
cache: npm
|
|
113
|
+
- run: npm ci
|
|
114
|
+
- uses: dgesteves/onsystem@v0
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
[Make it a required check on agent pull requests](https://onsystem.vercel.app/docs/required-check) has the whole workflow and its inputs.
|
|
100
118
|
|
|
101
119
|
**ESLint.** The same rules for ESLint 8.57, 9 and 10: add `onsystem.configs.recommended` from `onsystem/eslint` to `eslint.config.mjs` ([ESLint plugin](https://onsystem.vercel.app/docs/eslint), with @shadcn/lint).
|
|
102
120
|
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
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 LEGACY_CONFIG_FILES, A as unrecordedRules, At as relativePath, B as statusKinds, C as countBaseline, D as pruneBaseline, Dt as SCRIPT_FILE, E as onLines, Et as unique, J as ConfigError, L as toDesignMd, M as writeBaseline, Nt as readProjectConfig, O as readBaseline, Ot as isInside, R as toDtcg, S as applyBaseline, T as goneFiles, Y as DEFAULT_DOCS, _ as formatDiagnostics, _t as detectProject, b as BASELINE_FILE, c as silentLogger, et as RULE_IDS, ft as libraryTitle, g as escapeData, gt as declaredConfig, h as uncheckedNotice, i as componentFiles, j as updateBaseline, jt as toPosix, k as rulesRun, kt as matchesGlob, l as stderrLogger, mt as PACKAGE_FIELD, o as loadDesignSystem, pt as notReadYet, q as CONFIG_FILES, rt as excludedBy, s as tokenFiles, st as rulesFor, v as NAME, w as findMoves, wt as plural, x as LEGACY_BASELINE_FILE, y as VERSION, yt as isDesignSystemName } from "./design-system-DZm2aP1z.js";
|
|
3
|
+
import { a as notReadNotices, i as missingDependencies, o as explainProject, s as librariesLeftOut, t as serveStdio } from "./stdio-BJvjEnKW.js";
|
|
4
|
+
import { r as loadTarget } from "./workspace-Dqu3nkYM.js";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { escapePath, glob } from "tinyglobby";
|
|
@@ -169,6 +169,14 @@ async function init(configOptions, options, io, runCheck) {
|
|
|
169
169
|
const total = errors + warnings;
|
|
170
170
|
io.stdout(total ? `Dry run of \`${NAME} check .\`: ${count$1(errors, "error")} and ${count$1(warnings, "warning")} in ${flagged} of ${count$1(results.length, "file")}. By rule: ${[...byRule].sort((a, b) => b[1] - a[1]).map(([rule, n]) => `${rule} ${n.toLocaleString("en-US")}`).join(", ")}.` : `Dry run of \`${NAME} check .\`: no problems in ${count$1(results.length, "file")}.`);
|
|
171
171
|
for (const line of dry.stderr.split("\n").filter(Boolean)) io.stdout(line);
|
|
172
|
+
if (!workspace) {
|
|
173
|
+
const own = (await loadTarget({
|
|
174
|
+
...configOptions,
|
|
175
|
+
config: void 0
|
|
176
|
+
})).config;
|
|
177
|
+
const note = statusNote(await loadDesignSystem(own, { cache: options.cache }));
|
|
178
|
+
if (note) io.stdout(note);
|
|
179
|
+
}
|
|
172
180
|
const hasBaseline = [BASELINE_FILE, LEGACY_BASELINE_FILE].some((name) => fs.existsSync(path.join(root, name)));
|
|
173
181
|
let baselineWritten = false;
|
|
174
182
|
if (total && !hasBaseline) {
|
|
@@ -196,6 +204,28 @@ async function init(configOptions, options, io, runCheck) {
|
|
|
196
204
|
return 0;
|
|
197
205
|
}
|
|
198
206
|
const CONFIG_FILE = "onsystem.config.json";
|
|
207
|
+
/** The status colors docs/tokens.md#status-colors adds, and the hue each one is. */
|
|
208
|
+
const RECIPE = [
|
|
209
|
+
["success", "green"],
|
|
210
|
+
["warning", "yellow"],
|
|
211
|
+
["info", "blue"]
|
|
212
|
+
];
|
|
213
|
+
/**
|
|
214
|
+
* Says which of success, warning and info the theme has no color for, and where the CSS that adds
|
|
215
|
+
* them is: without one, an agent asked for a green "Active" label tends to reach for a chart or a
|
|
216
|
+
* gray token, which loses what the color says. Nothing when the theme has no colors, or all three.
|
|
217
|
+
*/
|
|
218
|
+
function statusNote(ds) {
|
|
219
|
+
if (!ds.tokens.some((token) => token.category === "color")) return void 0;
|
|
220
|
+
const has = statusKinds(ds.tokens);
|
|
221
|
+
const missing = RECIPE.filter(([kind]) => !has.has(kind));
|
|
222
|
+
if (!missing.length) return void 0;
|
|
223
|
+
return `The theme has no ${orList(missing.map(([kind]) => kind))} token, so a ${orList(missing.map(([, hue]) => hue))} status color has no token to use, and agents tend to reach for a chart or gray token instead. To add ${missing.length === 1 ? "it" : "them"}: https://onsystem.vercel.app/docs/tokens#status-colors.`;
|
|
224
|
+
}
|
|
225
|
+
/** `success, warning or info`. */
|
|
226
|
+
function orList(items) {
|
|
227
|
+
return items.length > 1 ? `${items.slice(0, -1).join(", ")} or ${items.at(-1) ?? ""}` : items[0] ?? "";
|
|
228
|
+
}
|
|
199
229
|
/** The instruction files agents read, which `init` offers to add onsystem's section to. */
|
|
200
230
|
const AGENT_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
201
231
|
const RULES_BEGIN = "<!-- BEGIN:onsystem-agent-rules -->";
|
|
@@ -906,17 +936,20 @@ async function check(patterns, configOptions, values, io) {
|
|
|
906
936
|
};
|
|
907
937
|
const disabledByKey = /* @__PURE__ */ new Map();
|
|
908
938
|
const realRoot = fs.realpathSync.native(selection.root);
|
|
909
|
-
const
|
|
939
|
+
const folders = patterns.map((pattern) => path.resolve(io.cwd, pattern)).filter((dir) => fs.statSync(dir, { throwIfNoEntry: false })?.isDirectory()).map(realPath);
|
|
940
|
+
const changedLines = baseline && !update ? readChangedLines(io.env ?? process.env, io.cwd) : void 0;
|
|
910
941
|
const results = [];
|
|
911
942
|
const checked = /* @__PURE__ */ new Map();
|
|
912
943
|
const ran = /* @__PURE__ */ new Set();
|
|
913
944
|
let baselined = 0;
|
|
914
945
|
let fixed = 0;
|
|
946
|
+
const unrecorded = [];
|
|
915
947
|
for (const file of files) {
|
|
916
948
|
const code = await fsp.readFile(file, "utf8");
|
|
917
949
|
const ds = selection.designSystemOf(file);
|
|
918
950
|
let result = ds.check(code, relativePath(ds.root, file));
|
|
919
|
-
const
|
|
951
|
+
const real = fs.realpathSync.native(file);
|
|
952
|
+
const key = relativePath(realRoot, real).normalize("NFC");
|
|
920
953
|
const disabled = disabledFor(file);
|
|
921
954
|
disabledByKey.set(key, disabled);
|
|
922
955
|
if (update || prune) checked.set(key, result.diagnostics);
|
|
@@ -924,28 +957,59 @@ async function check(patterns, configOptions, values, io) {
|
|
|
924
957
|
for (const rule of RULE_IDS) if (!disabled.has(rule) && canRun(ds, rule)) ran.add(rule);
|
|
925
958
|
}
|
|
926
959
|
if (baseline && !update) {
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
960
|
+
const changed = changedLines?.get(real);
|
|
961
|
+
if (baseline.entries.has(key)) {
|
|
962
|
+
const match = applyBaseline(baseline.entries, key, result, disabled, changed);
|
|
963
|
+
result = {
|
|
964
|
+
...match.result,
|
|
965
|
+
baselined: match.baselined
|
|
966
|
+
};
|
|
967
|
+
baselined += match.baselined;
|
|
968
|
+
fixed += match.fixed;
|
|
969
|
+
} else unrecorded.push({
|
|
970
|
+
index: results.length,
|
|
971
|
+
key,
|
|
972
|
+
result,
|
|
973
|
+
disabled,
|
|
974
|
+
changed
|
|
975
|
+
});
|
|
934
976
|
}
|
|
935
977
|
results.push({
|
|
936
978
|
...result,
|
|
937
979
|
file: relativePath(io.cwd, file)
|
|
938
980
|
});
|
|
939
981
|
}
|
|
982
|
+
let moves = /* @__PURE__ */ new Map();
|
|
983
|
+
if (baseline && !update) {
|
|
984
|
+
const covered = (key) => folders.some((dir) => isInside(dir, path.join(realRoot, key)));
|
|
985
|
+
const matching = unrecorded.some((u) => u.result.diagnostics.length);
|
|
986
|
+
const gone = goneFiles(baseline.entries, realRoot, new Set(disabledByKey.keys()), (key) => matching || covered(key));
|
|
987
|
+
const changedIn = new Map(unrecorded.map((u) => [u.key, u.changed]));
|
|
988
|
+
moves = findMoves(baseline.entries, new Map(unrecorded.map((u) => [u.key, u.result.diagnostics])), gone, (key) => disabledByKey.get(key) ?? /* @__PURE__ */ new Set(), (key, diagnostic) => onLines(changedIn.get(key), diagnostic));
|
|
989
|
+
for (const { index, key, result, disabled, changed } of unrecorded) {
|
|
990
|
+
const from = moves.get(key) ?? key;
|
|
991
|
+
const match = applyBaseline(baseline.entries, from, result, disabled, changed);
|
|
992
|
+
const file = results[index]?.file ?? result.file;
|
|
993
|
+
results[index] = {
|
|
994
|
+
...match.result,
|
|
995
|
+
baselined: match.baselined,
|
|
996
|
+
file
|
|
997
|
+
};
|
|
998
|
+
baselined += match.baselined;
|
|
999
|
+
fixed += match.fixed;
|
|
1000
|
+
}
|
|
1001
|
+
const moved = new Set(moves.values());
|
|
1002
|
+
for (const key of gone) {
|
|
1003
|
+
const rules = baseline.entries.get(key);
|
|
1004
|
+
if (rules && !moved.has(key) && covered(key)) fixed += countBaseline(/* @__PURE__ */ new Map([[key, rules]])).findings;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
940
1007
|
const elsewhere = results.filter((r) => r.skipped).length;
|
|
941
1008
|
if (elsewhere) notes.push(`${plural(elsewhere, "image or email file")} not checked`);
|
|
942
1009
|
const unchecked = uncheckedNotice(results);
|
|
943
1010
|
if (update) {
|
|
944
1011
|
const next = updateBaseline(baseline?.entries, checked, realRoot, (key) => disabledByKey.get(key) ?? /* @__PURE__ */ new Set());
|
|
945
|
-
const wholeRoot =
|
|
946
|
-
const dir = path.resolve(io.cwd, pattern);
|
|
947
|
-
return Boolean(fs.statSync(dir, { throwIfNoEntry: false })?.isDirectory() && isInside(realPath(dir), realRoot));
|
|
948
|
-
});
|
|
1012
|
+
const wholeRoot = folders.some((dir) => isInside(dir, realRoot));
|
|
949
1013
|
writeBaseline(baselineFile, next, {
|
|
950
1014
|
onsystem: VERSION,
|
|
951
1015
|
rules: rulesRun(baseline, next, checked, ran, wholeRoot)
|
|
@@ -966,15 +1030,16 @@ async function check(patterns, configOptions, values, io) {
|
|
|
966
1030
|
if (unrecorded.size) baselineNotes.push(unrecordedNote(unrecorded, fresh.length, baseline.onsystem, command("--update-baseline")));
|
|
967
1031
|
}
|
|
968
1032
|
if (prune && baseline) {
|
|
969
|
-
const next = pruneBaseline(baseline.entries, checked, realRoot, (key) => disabledByKey.get(key) ?? /* @__PURE__ */ new Set());
|
|
1033
|
+
const next = pruneBaseline(baseline.entries, checked, realRoot, (key) => disabledByKey.get(key) ?? /* @__PURE__ */ new Set(), moves);
|
|
970
1034
|
const left = countBaseline(next);
|
|
971
1035
|
const dropped = countBaseline(baseline.entries).findings - left.findings;
|
|
972
|
-
if (dropped) writeBaseline(baselineFile, next, {
|
|
1036
|
+
if (dropped || moves.size) writeBaseline(baselineFile, next, {
|
|
973
1037
|
onsystem: baseline.onsystem,
|
|
974
1038
|
rules: baseline.rules
|
|
975
1039
|
});
|
|
976
|
-
|
|
977
|
-
|
|
1040
|
+
const done = [moves.size ? `moved the findings of ${count(moves.size, "file")} to ${moves.size === 1 ? "its new path" : "their new paths"}` : "", dropped ? `dropped ${count(dropped, "finding")} that no longer ${dropped === 1 ? "occurs" : "occur"}` : ""].filter(Boolean);
|
|
1041
|
+
baselineNotes.push(`Baseline: ${done.join("; ") || "nothing to drop"}; ${count(left.findings, "finding")} in ${count(left.files, "file")} → ${displayPath(io.cwd, baselineFile)}`);
|
|
1042
|
+
} else if (moves.size) baselineNotes.push(movedNote(moves, command("--prune-baseline")));
|
|
978
1043
|
const output = formatDiagnostics(format === "json" ? results : results.filter((r) => !r.skipped), format, {
|
|
979
1044
|
color: io.color,
|
|
980
1045
|
uri: format === "sarif" || format === "github" ? repositoryPath(io.cwd, io.env ?? process.env) : void 0,
|
|
@@ -995,7 +1060,9 @@ async function check(patterns, configOptions, values, io) {
|
|
|
995
1060
|
const warnings = results.reduce((n, r) => n + r.warningCount, 0);
|
|
996
1061
|
if (errors > 0) return 1;
|
|
997
1062
|
if (maxWarnings !== void 0 && warnings > maxWarnings) {
|
|
998
|
-
|
|
1063
|
+
const message = `Too many warnings (${warnings}, max ${maxWarnings}).`;
|
|
1064
|
+
if (format === "github") io.stdout(`::error title=${NAME}::${message}`);
|
|
1065
|
+
else io.stderr(message);
|
|
999
1066
|
return 1;
|
|
1000
1067
|
}
|
|
1001
1068
|
return 0;
|
|
@@ -1647,6 +1714,40 @@ function canRun(ds, rule) {
|
|
|
1647
1714
|
default: return ds.model.components.length > 0;
|
|
1648
1715
|
}
|
|
1649
1716
|
}
|
|
1717
|
+
/** Says which files the baseline takes for moved, and how to record their new paths. */
|
|
1718
|
+
function movedNote(moves, prune) {
|
|
1719
|
+
const pairs = [...moves].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
1720
|
+
const [first] = pairs;
|
|
1721
|
+
if (pairs.length === 1 && first) return `Baseline: ${first[0]} has the findings recorded for ${first[1]}, which no longer exists, so they are accepted as moved. Run \`${prune}\` to record the new path.`;
|
|
1722
|
+
const list = listOf(pairs.map(([to, from]) => `${from} → ${to}`));
|
|
1723
|
+
return `Baseline: ${pairs.length} files have the findings recorded for files that no longer exist, so they are accepted as moved (${list}). Run \`${prune}\` to record the new paths.`;
|
|
1724
|
+
}
|
|
1725
|
+
/** The variable the GitHub Action names the pull request's changed lines in. */
|
|
1726
|
+
const CHANGED_LINES = "ONSYSTEM_CHANGED_LINES";
|
|
1727
|
+
/**
|
|
1728
|
+
* The lines a pull request changed, by the real path of each file: the JSON file that
|
|
1729
|
+
* ONSYSTEM_CHANGED_LINES names maps paths to 1-based ranges, `{ "/repo/app/page.tsx": [[4, 4]] }`.
|
|
1730
|
+
* The GitHub Action writes it. Undefined when the variable is not set.
|
|
1731
|
+
*/
|
|
1732
|
+
function readChangedLines(env, cwd) {
|
|
1733
|
+
const file = env[CHANGED_LINES]?.trim();
|
|
1734
|
+
if (!file) return void 0;
|
|
1735
|
+
const fail = (why) => new ConfigError(`${CHANGED_LINES}: ${why}. The GitHub Action sets this variable to a file of the lines a pull request changed; unset it when you run check yourself.`);
|
|
1736
|
+
let parsed;
|
|
1737
|
+
try {
|
|
1738
|
+
parsed = JSON.parse(fs.readFileSync(path.resolve(cwd, file), "utf8"));
|
|
1739
|
+
} catch (error) {
|
|
1740
|
+
throw fail(`could not read ${file}: ${error.message}`);
|
|
1741
|
+
}
|
|
1742
|
+
const range = (value) => Array.isArray(value) && value.length === 2 && value.every((n) => Number.isInteger(n));
|
|
1743
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw fail(`${file} must map files to line ranges`);
|
|
1744
|
+
const lines = /* @__PURE__ */ new Map();
|
|
1745
|
+
for (const [name, ranges] of Object.entries(parsed)) {
|
|
1746
|
+
if (!Array.isArray(ranges) || !ranges.every(range)) throw fail(`${file} › "${name}" must be a list of [start, end] lines`);
|
|
1747
|
+
lines.set(realPath(path.resolve(cwd, name)), ranges);
|
|
1748
|
+
}
|
|
1749
|
+
return lines;
|
|
1750
|
+
}
|
|
1650
1751
|
/** Why findings of rules that did not run when the baseline was recorded are new to it. */
|
|
1651
1752
|
function unrecordedNote(byRule, total, version, update) {
|
|
1652
1753
|
const rules = [...byRule.keys()].sort();
|
|
@@ -281,6 +281,11 @@ interface LibrarySource {
|
|
|
281
281
|
dir?: string | undefined;
|
|
282
282
|
/** The installed version. */
|
|
283
283
|
version?: string | undefined;
|
|
284
|
+
/**
|
|
285
|
+
* A design-system package installed without its component sources, read from its type
|
|
286
|
+
* declarations ({@link declarationsPackages}) rather than as a library onsystem knows.
|
|
287
|
+
*/
|
|
288
|
+
designSystem?: true | undefined;
|
|
284
289
|
}
|
|
285
290
|
//#endregion
|
|
286
291
|
//#region src/config.d.ts
|