onsystem 0.0.1 → 0.5.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/LICENSE +21 -0
- package/README.md +98 -2
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1019 -0
- package/dist/design-system-CnEv5sIL.js +7841 -0
- package/dist/eslint-worker.d.ts +36 -0
- package/dist/eslint-worker.js +88 -0
- package/dist/eslint.d.ts +23 -0
- package/dist/eslint.js +172 -0
- package/dist/index.d.ts +775 -0
- package/dist/index.js +3 -0
- package/dist/stdio-DjfkiDMV.js +1399 -0
- package/dist/types-DJtccu3A.d.ts +386 -0
- package/dist/workspace-DzWQ4L8R.js +193 -0
- package/package.json +124 -8
- package/schema.json +301 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
import { C as RuleId, D as loadConfig, E as defineConfig, O as ImportMapping, S as ResolvedRule, T as configJsonSchema, _ as VariantInfo, a as DesignSystemModel, b as RULE_IDS, c as ExampleInfo, d as Severity, f as SourceLocation, g as TokenCategory, h as Token, i as CompoundVariantInfo, l as InheritedProps, m as TextEdit, n as ComponentDocs, o as Diagnostic, p as TOKEN_CATEGORIES, r as ComponentInfo, s as DocSection, t as CheckResult, u as PropInfo, v as Config, w as RuleOptions, x as ResolvedConfig, y as LoadConfigOptions } from "./types-DJtccu3A.js";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import { Oklch } from "culori";
|
|
4
|
+
import { McpServer, Transport } from "@modelcontextprotocol/server";
|
|
5
|
+
//#region src/lint/analyze.d.ts
|
|
6
|
+
interface ImportBinding {
|
|
7
|
+
source: string;
|
|
8
|
+
/** Imported name, `default`, or `*` for namespace imports. */
|
|
9
|
+
imported: string;
|
|
10
|
+
}
|
|
11
|
+
interface JsxNode {
|
|
12
|
+
node: ts.JsxElement | ts.JsxSelfClosingElement;
|
|
13
|
+
opening: ts.JsxOpeningElement | ts.JsxSelfClosingElement;
|
|
14
|
+
closing?: ts.JsxClosingElement | undefined;
|
|
15
|
+
tagName: ts.JsxTagNameExpression;
|
|
16
|
+
/** Tag as written: `button`, `Button`, `Card.Header`. */
|
|
17
|
+
tag: string;
|
|
18
|
+
attributes: ts.JsxAttribute[];
|
|
19
|
+
hasSpread: boolean;
|
|
20
|
+
children: readonly ts.JsxChild[];
|
|
21
|
+
}
|
|
22
|
+
/** A run of literal class text with its absolute offset in the source. */
|
|
23
|
+
interface ClassString {
|
|
24
|
+
text: string;
|
|
25
|
+
start: number;
|
|
26
|
+
/** The JSX element whose `className` this is, if any. */
|
|
27
|
+
element?: JsxNode | undefined;
|
|
28
|
+
}
|
|
29
|
+
interface StyleObject {
|
|
30
|
+
element: JsxNode;
|
|
31
|
+
object: ts.ObjectLiteralExpression;
|
|
32
|
+
}
|
|
33
|
+
interface Analysis {
|
|
34
|
+
imports: Map<string, ImportBinding>;
|
|
35
|
+
declared: Set<string>;
|
|
36
|
+
elements: JsxNode[];
|
|
37
|
+
classStrings: ClassString[];
|
|
38
|
+
styles: StyleObject[];
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/modules.d.ts
|
|
42
|
+
/** Where an import points: a file relative to the root, or `{}` for a declared module not on disk. */
|
|
43
|
+
interface ModuleLocation {
|
|
44
|
+
file?: string;
|
|
45
|
+
}
|
|
46
|
+
/** What a module exports by name, and the modules it re-exports wholesale (`export * from`). */
|
|
47
|
+
interface ModuleExports {
|
|
48
|
+
/** Every name it exports, its own and re-exported ones. */
|
|
49
|
+
names: string[];
|
|
50
|
+
/** The names it declares itself (`export function Table`), not re-exports. */
|
|
51
|
+
declared: string[];
|
|
52
|
+
/** Files relative to the root; undefined where the specifier does not resolve. */
|
|
53
|
+
starFrom: (string | undefined)[];
|
|
54
|
+
/**
|
|
55
|
+
* Names it re-exports from another module, and under which name that module exports
|
|
56
|
+
* them: `export { Button } from "./Button"`, `export { Root as Dialog } from "./dialog"`,
|
|
57
|
+
* or an imported binding exported again. `from` is undefined where it does not resolve.
|
|
58
|
+
*/
|
|
59
|
+
reexports: Map<string, {
|
|
60
|
+
from: string | undefined;
|
|
61
|
+
name: string;
|
|
62
|
+
}>;
|
|
63
|
+
/** Names it exports as a module namespace (`export * as Radio from "./radio"`), not a component. */
|
|
64
|
+
namespaces: Set<string>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Finds the modules a checked file imports from the design system, and what
|
|
68
|
+
* they export, so the linter can tell a name the model left out (an excluded
|
|
69
|
+
* folder, a package built to `dist/`) from an invented one. It resolves through
|
|
70
|
+
* tsconfig `paths`, relative paths and workspace packages, reads files only
|
|
71
|
+
* when asked, and caches both. Where the root is not on disk (the website's
|
|
72
|
+
* playground), it finds nothing, and every missing name counts as invented.
|
|
73
|
+
*/
|
|
74
|
+
declare class ModuleResolver {
|
|
75
|
+
private readonly config;
|
|
76
|
+
private resolveFn?;
|
|
77
|
+
private readonly locations;
|
|
78
|
+
private readonly exported;
|
|
79
|
+
constructor(config: Pick<ResolvedConfig, 'root' | 'tsconfig'>);
|
|
80
|
+
/** The module `specifier` points at from `fromFile` (relative to the root). */
|
|
81
|
+
locate(specifier: string, fromFile: string): ModuleLocation | undefined;
|
|
82
|
+
/** What a module exports, read from its source without type-checking. */
|
|
83
|
+
exportsOf(file: string): ModuleExports | undefined;
|
|
84
|
+
private createResolver;
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/tokens/roles.d.ts
|
|
88
|
+
/**
|
|
89
|
+
* What a color utility paints, which decides the tokens that fit it: `text-*`
|
|
90
|
+
* wants a foreground, `bg-*` a surface, `border-*` a border color.
|
|
91
|
+
*/
|
|
92
|
+
type ColorRole = 'text' | 'surface' | 'line';
|
|
93
|
+
/**
|
|
94
|
+
* Token families made for one part of the UI. `sidebar-accent` has the value
|
|
95
|
+
* of `accent` and `chart-2` that of `muted-foreground`, but they only belong
|
|
96
|
+
* in a sidebar or a chart. Beyond these two, any family that is not named for
|
|
97
|
+
* a role and that at most one design-system file uses is scoped the same way:
|
|
98
|
+
* syntax-highlighting colors (`sh-class`), a chart palette (`rainbow-4`), one
|
|
99
|
+
* screen's background (`envelope-editor-background`), or a copy of Tailwind's
|
|
100
|
+
* palette (`color-red-500`).
|
|
101
|
+
*/
|
|
102
|
+
type ScopedFamily = string;
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/tokens/css.d.ts
|
|
105
|
+
/**
|
|
106
|
+
* Reads design tokens from CSS custom properties, the way shadcn/ui and
|
|
107
|
+
* Tailwind v4 projects define them:
|
|
108
|
+
*
|
|
109
|
+
* - `:root { --primary: oklch(...) }` holds the values,
|
|
110
|
+
* - `.dark { --primary: ... }` (or a dark media query / data attribute) holds modes,
|
|
111
|
+
* - `@theme inline { --color-primary: var(--primary) }` exposes them to Tailwind.
|
|
112
|
+
*/
|
|
113
|
+
export declare function parseCssTokens(css: string, file: string): {
|
|
114
|
+
tokens: Token[];
|
|
115
|
+
warnings: string[];
|
|
116
|
+
};
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/tokens/dtcg.d.ts
|
|
119
|
+
interface DtcgOptions {
|
|
120
|
+
/** Prefix for generated custom property names: `ds` → `--ds-color-primary`. */
|
|
121
|
+
prefix?: string;
|
|
122
|
+
}
|
|
123
|
+
export declare function parseDtcgTokens(text: string, file: string, options?: DtcgOptions): {
|
|
124
|
+
tokens: Token[];
|
|
125
|
+
warnings: string[];
|
|
126
|
+
};
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/tokens/index.d.ts
|
|
129
|
+
interface TokenSource {
|
|
130
|
+
file: string;
|
|
131
|
+
/** DTCG only: prefix for generated custom property names. */
|
|
132
|
+
prefix?: string | undefined;
|
|
133
|
+
}
|
|
134
|
+
export declare function loadTokens(root: string, sources: TokenSource[]): Promise<{
|
|
135
|
+
tokens: Token[];
|
|
136
|
+
warnings: string[];
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* DTCG files and the CSS generated from them often describe the same tokens.
|
|
140
|
+
* Merge entries that share a custom property: keep the DTCG name and
|
|
141
|
+
* description, and add the Tailwind mapping from CSS.
|
|
142
|
+
*/
|
|
143
|
+
export declare function mergeTokens(tokens: Token[]): Token[];
|
|
144
|
+
interface ColorCandidate {
|
|
145
|
+
token: Token;
|
|
146
|
+
color: Oklch;
|
|
147
|
+
/** Values in other theme modes (`dark`), where the token has one. */
|
|
148
|
+
modes?: Record<string, Oklch>;
|
|
149
|
+
}
|
|
150
|
+
interface LengthCandidate {
|
|
151
|
+
token: Token;
|
|
152
|
+
px: number;
|
|
153
|
+
/** Tailwind key for the step (`3` for `p-3`, `md` for `rounded-md`), if any. */
|
|
154
|
+
key?: string;
|
|
155
|
+
}
|
|
156
|
+
interface Nearest<T> {
|
|
157
|
+
candidate: T;
|
|
158
|
+
distance: number;
|
|
159
|
+
}
|
|
160
|
+
interface ColorQuery {
|
|
161
|
+
/** What the color paints: `text-*` is best served by a foreground, `bg-*` by a surface. */
|
|
162
|
+
role?: ColorRole | undefined;
|
|
163
|
+
/** The scoped families the code is in (`sidebar` in `app-sidebar.tsx`), whose tokens then compete like any other. */
|
|
164
|
+
scopes?: ReadonlySet<ScopedFamily> | undefined;
|
|
165
|
+
/** Whether the color is a hue rather than a gray. Default: from its chroma. */
|
|
166
|
+
tinted?: boolean | undefined;
|
|
167
|
+
/** The theme mode the color applies in (`dark` for `dark:bg-*`): tokens are compared by their value there. */
|
|
168
|
+
mode?: string | undefined;
|
|
169
|
+
}
|
|
170
|
+
interface ColorSuggestion {
|
|
171
|
+
/** A token that can replace the color as is: close, of the same hue (or both gray), and not made for another role. */
|
|
172
|
+
match?: Nearest<ColorCandidate> | undefined;
|
|
173
|
+
/** The token to name: the match, else the nearest, preferring the same hue and the role. */
|
|
174
|
+
nearest: Nearest<ColorCandidate>;
|
|
175
|
+
/**
|
|
176
|
+
* Why the nearest token is no match: no token of its hue (or no gray), too far,
|
|
177
|
+
* made for another role, a status color whose hue is not close enough, or a
|
|
178
|
+
* token of a family scoped to another part of the UI.
|
|
179
|
+
*/
|
|
180
|
+
reason?: 'far' | 'hue' | 'role' | 'status' | 'scoped' | undefined;
|
|
181
|
+
/** With reason `status`: how far apart the hues are, in degrees. */
|
|
182
|
+
hueOff?: number | undefined;
|
|
183
|
+
/** Other tokens with the nearest one's value. */
|
|
184
|
+
sameValue: Token[];
|
|
185
|
+
}
|
|
186
|
+
interface NearestLength extends Nearest<LengthCandidate> {
|
|
187
|
+
/** A radius so far above the scale that it means "fully rounded" (`rounded-full`). */
|
|
188
|
+
pill?: boolean;
|
|
189
|
+
}
|
|
190
|
+
/** Query helpers over the token list: lookups and nearest-token search. */
|
|
191
|
+
export declare class TokenIndex {
|
|
192
|
+
readonly tokens: Token[];
|
|
193
|
+
readonly colors: ColorCandidate[];
|
|
194
|
+
readonly spacing: LengthCandidate[];
|
|
195
|
+
readonly radius: LengthCandidate[];
|
|
196
|
+
/** Tailwind color keys the design system defines (`primary`, `muted-foreground`). */
|
|
197
|
+
readonly colorKeys: Set<string>;
|
|
198
|
+
/** Base unit when spacing follows Tailwind's multiplier model. */
|
|
199
|
+
readonly spacingUnitPx: number | undefined;
|
|
200
|
+
private readonly spacingUnit;
|
|
201
|
+
private readonly byVar;
|
|
202
|
+
/** Families suggested only in their own part of the UI (`sidebar`, `chart`, `sh`). */
|
|
203
|
+
readonly scopedFamilies: ReadonlySet<ScopedFamily>;
|
|
204
|
+
/** Family → the design-system files that use its tokens. */
|
|
205
|
+
readonly familyFiles: ReadonlyMap<string, ReadonlySet<string>>;
|
|
206
|
+
/**
|
|
207
|
+
* `filesUsing` maps each token family to the design-system files that use it;
|
|
208
|
+
* a family that at most one of them uses is scoped. Without it, only sidebar
|
|
209
|
+
* and chart are.
|
|
210
|
+
*/
|
|
211
|
+
constructor(tokens: Token[], options?: {
|
|
212
|
+
filesUsing?: ReadonlyMap<string, ReadonlySet<string>> | undefined;
|
|
213
|
+
});
|
|
214
|
+
has(category: TokenCategory): boolean;
|
|
215
|
+
byCssVar(name: string): Token | undefined;
|
|
216
|
+
/** The scoped family a token belongs to, if any. */
|
|
217
|
+
scopedFamilyOf(token: Token): ScopedFamily | undefined;
|
|
218
|
+
nearestColor(color: Oklch, limit?: number): Nearest<ColorCandidate>[];
|
|
219
|
+
/**
|
|
220
|
+
* The token to suggest for a color. Perceptual distance alone picks badly:
|
|
221
|
+
* several tokens share a value (`muted`, `accent`, `sidebar-accent`,
|
|
222
|
+
* `chart-2`...), and a pale yellow sits 0.07 from a light gray. So among the
|
|
223
|
+
* tokens close enough to swap in, of the same hue, it prefers the ones made
|
|
224
|
+
* for the role (`muted-foreground` for `text-gray-500`), and sidebar and
|
|
225
|
+
* chart tokens only in a sidebar or a chart.
|
|
226
|
+
*/
|
|
227
|
+
suggestColor(color: Oklch, query?: ColorQuery): ColorSuggestion | undefined;
|
|
228
|
+
/** The step closest to the magnitude of `px`; callers keep the sign. */
|
|
229
|
+
nearestLength(category: 'spacing' | 'radius', px: number): NearestLength | undefined;
|
|
230
|
+
/**
|
|
231
|
+
* Tailwind v4 derives `p-<n>` from `--spacing` for any n. Whole and half
|
|
232
|
+
* steps (`p-13`, `p-4.5`) count as the scale, plus the static `p-px`;
|
|
233
|
+
* quarter steps are valid but off-grid, like the arbitrary values they replace.
|
|
234
|
+
*/
|
|
235
|
+
private spacingSteps;
|
|
236
|
+
/** px value of a token-like length string, resolving `var()` against the token set. */
|
|
237
|
+
toPx(value: string): number | undefined;
|
|
238
|
+
}
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/lint/target.d.ts
|
|
241
|
+
/** What the lint rules need to know about the design system. */
|
|
242
|
+
declare class LintTarget {
|
|
243
|
+
readonly model: DesignSystemModel;
|
|
244
|
+
readonly config: Pick<ResolvedConfig, 'elements' | 'importPath'> & Partial<Pick<ResolvedConfig, 'designSystems'>>;
|
|
245
|
+
private readonly resolver?;
|
|
246
|
+
readonly components: Map<string, ComponentInfo>;
|
|
247
|
+
/** Every component under each name and alias, when two design systems share one (`Button`). */
|
|
248
|
+
private readonly named;
|
|
249
|
+
readonly tokens: TokenIndex;
|
|
250
|
+
/** Native element → the component that replaces it. */
|
|
251
|
+
readonly elements: Map<string, ComponentInfo>;
|
|
252
|
+
/** The `elements` entries the config sets explicitly. */
|
|
253
|
+
private readonly configured;
|
|
254
|
+
readonly componentFiles: Set<string>;
|
|
255
|
+
/** Every value the component files export, components or not (`Icons`, `buttonVariants`). */
|
|
256
|
+
readonly exports: Set<string>;
|
|
257
|
+
private readonly importPaths;
|
|
258
|
+
private readonly importPrefixes;
|
|
259
|
+
/** Component files relative to the root, without extension (`components/ui/button`). */
|
|
260
|
+
private readonly componentModules;
|
|
261
|
+
private readonly moduleDirs;
|
|
262
|
+
/** The files extraction read, when the model says. */
|
|
263
|
+
private readonly sources?;
|
|
264
|
+
/**
|
|
265
|
+
* `resolver` finds the module an import points at and what it exports
|
|
266
|
+
* (`@calcom/ui/components/icon` → `components/icon/index.ts`), so a name from
|
|
267
|
+
* a module the model left out is not taken for an invented one. Without it,
|
|
268
|
+
* every missing name is invented.
|
|
269
|
+
*/
|
|
270
|
+
constructor(model: DesignSystemModel, config: Pick<ResolvedConfig, 'elements' | 'importPath'> & Partial<Pick<ResolvedConfig, 'designSystems'>>, resolver?: Pick<ModuleResolver, "locate" | "exportsOf"> | undefined);
|
|
271
|
+
/**
|
|
272
|
+
* Whether an import specifier points at the design system. Relative
|
|
273
|
+
* specifiers are resolved against `fromFile` (relative to the root) and
|
|
274
|
+
* must land on a component file, in a directory that holds one, or on that
|
|
275
|
+
* directory itself (a barrel: `../components/ui` and its index).
|
|
276
|
+
*/
|
|
277
|
+
isDesignSystemImport(specifier: string, fromFile?: string): boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Whether `name`, imported from the design system, may be a real export the
|
|
280
|
+
* model left out rather than an invented one: its module exists outside the
|
|
281
|
+
* folders extraction read and exports `name`, or re-exports from such a
|
|
282
|
+
* module (an excluded `icons/` folder, a barrel's `export * from "./icons"`).
|
|
283
|
+
* A module declared in a package's `exports` but not on disk counts too,
|
|
284
|
+
* except the design system's own import path.
|
|
285
|
+
*/
|
|
286
|
+
outsideModel(specifier: string, name: string, fromFile?: string): boolean;
|
|
287
|
+
/**
|
|
288
|
+
* The component a JSX tag means when `name` is imported from `specifier`, among the
|
|
289
|
+
* model's components of that name: the one declared where the import leads, through
|
|
290
|
+
* barrels (`export { Button } from "./Button"`, `export *`). `undefined` when it leads to
|
|
291
|
+
* a declaration the model does not have (another package's `Button`, or a file of the
|
|
292
|
+
* same name outside the component folders), which is not ours to check. Where the import
|
|
293
|
+
* cannot be followed, the component of that name, as before.
|
|
294
|
+
*/
|
|
295
|
+
componentFor(name: string, specifier: string, fromFile: string): ComponentInfo | undefined;
|
|
296
|
+
/**
|
|
297
|
+
* Where what `file` exports as `name` is declared, following re-exports: the file
|
|
298
|
+
* (relative to the root) and its name there, `{ namespace }` for a module namespace,
|
|
299
|
+
* `undefined` when it does not export it, `null` when a step of the way does not
|
|
300
|
+
* resolve or cannot be read.
|
|
301
|
+
*/
|
|
302
|
+
private originOf;
|
|
303
|
+
private mayExport;
|
|
304
|
+
/**
|
|
305
|
+
* Whether `<Component>` can replace the native element `key` (`a`,
|
|
306
|
+
* `input[type=checkbox]`) by renaming the tag: the config maps it, it
|
|
307
|
+
* renders that element, or it takes the element's own attributes.
|
|
308
|
+
*/
|
|
309
|
+
isDropIn(component: ComponentInfo, key: string): boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Whether a component asks for nothing beyond what the element takes: no
|
|
312
|
+
* required prop of its own, and the element's own attributes (`htmlFor` for a
|
|
313
|
+
* label). Unknown when its props do not fully resolve, so false.
|
|
314
|
+
*/
|
|
315
|
+
private plainFor;
|
|
316
|
+
/** The component a module exports as `default`, for `import Anything from "..."`. */
|
|
317
|
+
defaultExport(specifier: string, fromFile?: string): ComponentInfo | undefined;
|
|
318
|
+
private resolveRelative;
|
|
319
|
+
/** Component names for "did you mean" suggestions. */
|
|
320
|
+
names(): string[];
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/lint/context.d.ts
|
|
324
|
+
interface Report {
|
|
325
|
+
start: number;
|
|
326
|
+
end: number;
|
|
327
|
+
message: string;
|
|
328
|
+
suggestion?: string | undefined;
|
|
329
|
+
fix?: TextEdit[] | undefined;
|
|
330
|
+
/** Rules may downgrade (never upgrade) their configured severity for low-confidence findings. */
|
|
331
|
+
severity?: Severity;
|
|
332
|
+
}
|
|
333
|
+
interface RuleContext {
|
|
334
|
+
file: string;
|
|
335
|
+
text: string;
|
|
336
|
+
sourceFile: ts.SourceFile;
|
|
337
|
+
target: LintTarget;
|
|
338
|
+
analysis: Analysis;
|
|
339
|
+
options: RuleOptions;
|
|
340
|
+
/** True when the checked file is one of the design system's own component sources. */
|
|
341
|
+
isDesignSystemSource: boolean;
|
|
342
|
+
resolve(element: JsxNode): Resolution;
|
|
343
|
+
report(report: Report): void;
|
|
344
|
+
/** Records a component the model does not include, which the rules cannot check. */
|
|
345
|
+
unchecked(name: string, module: string): void;
|
|
346
|
+
}
|
|
347
|
+
interface Rule {
|
|
348
|
+
id: RuleId;
|
|
349
|
+
description: string;
|
|
350
|
+
run(context: RuleContext): void;
|
|
351
|
+
}
|
|
352
|
+
type Resolution =
|
|
353
|
+
/** A design-system component. */
|
|
354
|
+
{
|
|
355
|
+
kind: 'component';
|
|
356
|
+
component: ComponentInfo;
|
|
357
|
+
} |
|
|
358
|
+
/** A lowercase JSX tag. */
|
|
359
|
+
{
|
|
360
|
+
kind: 'intrinsic';
|
|
361
|
+
tag: string;
|
|
362
|
+
} |
|
|
363
|
+
/** Imported from the design system's path, but the design system has no such component. */
|
|
364
|
+
{
|
|
365
|
+
kind: 'missing-export';
|
|
366
|
+
name: string;
|
|
367
|
+
source: string;
|
|
368
|
+
} |
|
|
369
|
+
/** `Card.Header` where `Card` is a design-system component without that member. */
|
|
370
|
+
{
|
|
371
|
+
kind: 'missing-member';
|
|
372
|
+
owner: ComponentInfo;
|
|
373
|
+
member: string;
|
|
374
|
+
} |
|
|
375
|
+
/** Not imported, not declared and not a design-system component. */
|
|
376
|
+
{
|
|
377
|
+
kind: 'unresolved';
|
|
378
|
+
name: string;
|
|
379
|
+
} |
|
|
380
|
+
/** Imported from elsewhere or declared locally: not our business. */
|
|
381
|
+
{
|
|
382
|
+
kind: 'external';
|
|
383
|
+
};
|
|
384
|
+
//#endregion
|
|
385
|
+
//#region src/lint/rules/index.d.ts
|
|
386
|
+
/** Every rule, in the order they run. */
|
|
387
|
+
export declare const RULES: readonly Rule[];
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/lint/format.d.ts
|
|
390
|
+
type OutputFormat = 'pretty' | 'json' | 'github' | 'sarif';
|
|
391
|
+
/**
|
|
392
|
+
* Renders check results:
|
|
393
|
+
* - `pretty`: grouped by file, for terminals and agents,
|
|
394
|
+
* - `json`: the raw results,
|
|
395
|
+
* - `github`: workflow commands that GitHub Actions turns into PR annotations,
|
|
396
|
+
* - `sarif`: a SARIF 2.1.0 log, for GitHub code scanning and other SARIF consumers.
|
|
397
|
+
*/
|
|
398
|
+
export declare function formatDiagnostics(results: CheckResult[], format: OutputFormat, options?: {
|
|
399
|
+
color?: boolean;
|
|
400
|
+
/** Findings a baseline accepted; set when a baseline was applied. */
|
|
401
|
+
baselined?: number | undefined;
|
|
402
|
+
/** Says that baseline entries no longer occur, and how to drop them. */
|
|
403
|
+
fixedHint?: string | undefined;
|
|
404
|
+
/** What the run left out: `5 design-system files skipped`, `12 tests and stories left out`. */
|
|
405
|
+
notes?: readonly string[] | undefined;
|
|
406
|
+
/**
|
|
407
|
+
* `sarif` and `github`: a result's file as a path relative to the repository root, which
|
|
408
|
+
* code scanning and workflow commands resolve locations against.
|
|
409
|
+
*/
|
|
410
|
+
uri?: ((file: string) => string) | undefined;
|
|
411
|
+
}): string;
|
|
412
|
+
//#endregion
|
|
413
|
+
//#region src/lint/index.d.ts
|
|
414
|
+
interface CheckOptions {
|
|
415
|
+
/** File name used in results and to pick TSX vs JSX parsing. Default `snippet.tsx`. */
|
|
416
|
+
filename?: string | undefined;
|
|
417
|
+
rules: Record<RuleId, ResolvedRule>;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Lints a TSX/JSX snippet or file against the design system. Purely
|
|
421
|
+
* syntactic: no type-checking of the snippet, so it works on fragments an
|
|
422
|
+
* agent has not saved yet.
|
|
423
|
+
*/
|
|
424
|
+
export declare function checkSource(code: string, target: LintTarget, options: CheckOptions): CheckResult;
|
|
425
|
+
/** Applies non-overlapping fixes from the end of the file backwards. */
|
|
426
|
+
export declare function applyFixes(code: string, diagnostics: Diagnostic[]): string;
|
|
427
|
+
//#endregion
|
|
428
|
+
//#region src/search/bm25.d.ts
|
|
429
|
+
/**
|
|
430
|
+
* Okapi BM25 over weighted fields (BM25F-style: field weights scale term
|
|
431
|
+
* frequency and document length). Small, dependency-free and deterministic,
|
|
432
|
+
* which is what a local tool index of a few hundred documents needs.
|
|
433
|
+
*/
|
|
434
|
+
interface Bm25Options {
|
|
435
|
+
k1?: number;
|
|
436
|
+
b?: number;
|
|
437
|
+
}
|
|
438
|
+
interface Bm25Hit<T> {
|
|
439
|
+
item: T;
|
|
440
|
+
score: number;
|
|
441
|
+
/** Matched query terms, best first. */
|
|
442
|
+
terms: string[];
|
|
443
|
+
}
|
|
444
|
+
declare class Bm25Index<T> {
|
|
445
|
+
private readonly docs;
|
|
446
|
+
private readonly df;
|
|
447
|
+
private totalLength;
|
|
448
|
+
private readonly k1;
|
|
449
|
+
private readonly b;
|
|
450
|
+
constructor(options?: Bm25Options);
|
|
451
|
+
/** Adds a document as `[terms, weight]` fields. */
|
|
452
|
+
add(item: T, fields: [terms: string[], weight: number][]): void;
|
|
453
|
+
get size(): number;
|
|
454
|
+
search(query: Map<string, number>, limit?: number): Bm25Hit<T>[];
|
|
455
|
+
}
|
|
456
|
+
//#endregion
|
|
457
|
+
//#region src/search/index.d.ts
|
|
458
|
+
interface SearchHit {
|
|
459
|
+
component: ComponentInfo;
|
|
460
|
+
score: number;
|
|
461
|
+
matched: string[];
|
|
462
|
+
}
|
|
463
|
+
export declare function searchComponents(index: Bm25Index<ComponentInfo>, query: string, limit?: number): SearchHit[];
|
|
464
|
+
//#endregion
|
|
465
|
+
//#region src/util/log.d.ts
|
|
466
|
+
/**
|
|
467
|
+
* Diagnostics go to stderr: in stdio mode stdout carries JSON-RPC and must
|
|
468
|
+
* never receive anything else.
|
|
469
|
+
*/
|
|
470
|
+
interface Logger {
|
|
471
|
+
info(message: string): void;
|
|
472
|
+
warn(message: string): void;
|
|
473
|
+
error(message: string): void;
|
|
474
|
+
}
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/design-system.d.ts
|
|
477
|
+
/** A loaded design system: the model plus the indexes the tools query. */
|
|
478
|
+
export declare class DesignSystem {
|
|
479
|
+
readonly model: DesignSystemModel;
|
|
480
|
+
readonly config: ResolvedConfig;
|
|
481
|
+
readonly lint: LintTarget;
|
|
482
|
+
private readonly searchIndex;
|
|
483
|
+
constructor(model: DesignSystemModel, config: ResolvedConfig);
|
|
484
|
+
get root(): string;
|
|
485
|
+
get components(): ComponentInfo[];
|
|
486
|
+
get tokens(): Token[];
|
|
487
|
+
get tokenIndex(): TokenIndex;
|
|
488
|
+
/** Top-level components, i.e. not parts of another component. */
|
|
489
|
+
roots(): ComponentInfo[];
|
|
490
|
+
/** Looks a component up by name, alias, `Card.Header`/`CardHeader` or case-insensitively. */
|
|
491
|
+
getComponent(name: string): ComponentInfo | undefined;
|
|
492
|
+
suggestComponent(name: string): string | undefined;
|
|
493
|
+
search(query: string, limit?: number): SearchHit[];
|
|
494
|
+
/** Tokens, core ones first: scoped families (`sidebar-*`, `chart-*`) follow the rest, which an agent should reach for. */
|
|
495
|
+
getTokens(filter?: {
|
|
496
|
+
category?: TokenCategory | undefined;
|
|
497
|
+
query?: string | undefined;
|
|
498
|
+
}): Token[];
|
|
499
|
+
/** Tokens a component's classes and CSS variables reference, e.g. `bg-primary` → `primary`. */
|
|
500
|
+
relatedTokens(component: ComponentInfo): Token[];
|
|
501
|
+
/**
|
|
502
|
+
* What the rules could not check, when it matters: without components the
|
|
503
|
+
* component rules find nothing, and without color tokens neither does
|
|
504
|
+
* no-hardcoded-color, so a clean result says little. Undefined when both exist.
|
|
505
|
+
* `where` names the projects it applies to, at a workspace root: `in apps/web`.
|
|
506
|
+
*/
|
|
507
|
+
notice(where?: string): string | undefined;
|
|
508
|
+
check(code: string, filename?: string): CheckResult;
|
|
509
|
+
}
|
|
510
|
+
interface LoadOptions {
|
|
511
|
+
/** Use the on-disk extraction cache. Default true. */
|
|
512
|
+
cache?: boolean;
|
|
513
|
+
logger?: Logger;
|
|
514
|
+
/** Previous TypeScript program, reused for incremental rebuilds. */
|
|
515
|
+
oldProgram?: ts.Program | undefined;
|
|
516
|
+
}
|
|
517
|
+
interface BuildResult {
|
|
518
|
+
model: DesignSystemModel;
|
|
519
|
+
program?: ts.Program | undefined;
|
|
520
|
+
/** Fingerprint of every input file; unchanged fingerprint means nothing to rebuild. */
|
|
521
|
+
key?: string;
|
|
522
|
+
/** Project files the model depends on beyond the tracked ones; pass them to `fingerprint`. */
|
|
523
|
+
dependencies?: string[];
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Fingerprint of the files a config tracks (paths, sizes, mtimes), plus the
|
|
527
|
+
* `dependencies` of a previous build, without extracting anything.
|
|
528
|
+
*/
|
|
529
|
+
export declare function fingerprint(config: ResolvedConfig, dependencies?: readonly string[]): Promise<string>;
|
|
530
|
+
export declare function buildModel(config: ResolvedConfig, options?: LoadOptions): Promise<BuildResult>;
|
|
531
|
+
export declare function loadDesignSystem(config: ResolvedConfig, options?: LoadOptions): Promise<DesignSystem>;
|
|
532
|
+
/**
|
|
533
|
+
* Owns the current DesignSystem. Loads lazily, rebuilds when watched files
|
|
534
|
+
* change (reusing the previous TypeScript program), and never serves a
|
|
535
|
+
* half-built model: callers get the in-flight build when one is running.
|
|
536
|
+
*/
|
|
537
|
+
interface HostOptions extends LoadOptions {
|
|
538
|
+
/** Builds the model; replaceable in tests. Defaults to `buildModel`. */
|
|
539
|
+
build?: typeof buildModel;
|
|
540
|
+
/**
|
|
541
|
+
* Re-reads the config when its file changes while watching. Defaults to
|
|
542
|
+
* loading the same config file; pass your own to keep overrides such as CLI flags.
|
|
543
|
+
*/
|
|
544
|
+
loadConfig?: () => Promise<ResolvedConfig>;
|
|
545
|
+
}
|
|
546
|
+
export declare class DesignSystemHost {
|
|
547
|
+
private config;
|
|
548
|
+
private readonly options;
|
|
549
|
+
private current?;
|
|
550
|
+
private program?;
|
|
551
|
+
private key?;
|
|
552
|
+
private dependencies;
|
|
553
|
+
/** Bumped by every build; only the latest may update the state above. */
|
|
554
|
+
private generation;
|
|
555
|
+
private configChanged;
|
|
556
|
+
private watchers;
|
|
557
|
+
/** Recursively watched directories, and the config files watched through their directory. */
|
|
558
|
+
private watchedRoots;
|
|
559
|
+
private readonly watchedDirs;
|
|
560
|
+
private readonly watchedFiles;
|
|
561
|
+
private timer?;
|
|
562
|
+
private readonly listeners;
|
|
563
|
+
constructor(config: ResolvedConfig, options?: HostOptions);
|
|
564
|
+
get(): Promise<DesignSystem>;
|
|
565
|
+
reload(): Promise<DesignSystem>;
|
|
566
|
+
onChange(listener: (ds: DesignSystem) => void): () => void;
|
|
567
|
+
/** Watches the component, token and docs locations, the config and the tsconfig chain. */
|
|
568
|
+
watch(): void;
|
|
569
|
+
/**
|
|
570
|
+
* Watches the config file, the tsconfig and the tsconfigs it extends through
|
|
571
|
+
* their directories: editors save by renaming a new file over the old one,
|
|
572
|
+
* which ends a watch on the file. Called again after each build, so a new
|
|
573
|
+
* `extends` target is picked up.
|
|
574
|
+
*/
|
|
575
|
+
private watchConfigFiles;
|
|
576
|
+
private changed;
|
|
577
|
+
close(): void;
|
|
578
|
+
private watchDirectory;
|
|
579
|
+
private schedule;
|
|
580
|
+
/** Re-reads the config, re-watches what it points at and rebuilds. */
|
|
581
|
+
private reloadConfig;
|
|
582
|
+
private build;
|
|
583
|
+
}
|
|
584
|
+
//#endregion
|
|
585
|
+
//#region src/extract/components.d.ts
|
|
586
|
+
interface ExtractComponentsOptions {
|
|
587
|
+
root: string;
|
|
588
|
+
/** Absolute paths of the component source files. */
|
|
589
|
+
files: string[];
|
|
590
|
+
tsconfig?: string | undefined;
|
|
591
|
+
/** Package name the design system is imported from; overrides tsconfig path inference. */
|
|
592
|
+
importPath?: string | undefined;
|
|
593
|
+
/** Specifiers from the `exports` of the package that holds the components; checked before tsconfig paths. */
|
|
594
|
+
imports?: ImportMapping[] | undefined;
|
|
595
|
+
/** Previous program, to let TypeScript reuse unchanged source files when watching. */
|
|
596
|
+
oldProgram?: ts.Program | undefined;
|
|
597
|
+
}
|
|
598
|
+
interface ExtractComponentsResult {
|
|
599
|
+
components: ComponentInfo[];
|
|
600
|
+
propSets: Record<string, string[]>;
|
|
601
|
+
/** Every value the component files export, components or not (`Icons`, `buttonVariants`). */
|
|
602
|
+
exports: string[];
|
|
603
|
+
warnings: string[];
|
|
604
|
+
program: ts.Program;
|
|
605
|
+
/** Project files extraction depends on: the tsconfig chain and every module the components import. */
|
|
606
|
+
dependencies: string[];
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Extracts React components from source with the TypeScript checker: props
|
|
610
|
+
* (types, required, defaults, JSDoc), `cva()`/`tv()` variants, the native
|
|
611
|
+
* element they wrap, and compound structure (`CardHeader` under `Card`,
|
|
612
|
+
* `Tabs.List` via static members or `Object.assign`).
|
|
613
|
+
*/
|
|
614
|
+
export declare function extractComponents(options: ExtractComponentsOptions): ExtractComponentsResult;
|
|
615
|
+
//#endregion
|
|
616
|
+
//#region src/extract/cva.d.ts
|
|
617
|
+
/** A `cva()` (class-variance-authority) or `tv()` (tailwind-variants) definition. */
|
|
618
|
+
interface VariantDefinition {
|
|
619
|
+
/** The variable it is assigned to, e.g. `buttonVariants`. */
|
|
620
|
+
name: string;
|
|
621
|
+
base: string;
|
|
622
|
+
variants: VariantInfo[];
|
|
623
|
+
compoundVariants: CompoundVariantInfo[];
|
|
624
|
+
node: ts.CallExpression;
|
|
625
|
+
}
|
|
626
|
+
/** Finds every `const x = cva(base, { variants, defaultVariants })` in a file. */
|
|
627
|
+
export declare function findVariantDefinitions(sourceFile: ts.SourceFile): Map<string, VariantDefinition>;
|
|
628
|
+
//#endregion
|
|
629
|
+
//#region src/extract/docs.d.ts
|
|
630
|
+
interface ParsedDoc {
|
|
631
|
+
file: string;
|
|
632
|
+
title?: string;
|
|
633
|
+
description?: string;
|
|
634
|
+
sections: DocSection[];
|
|
635
|
+
examples: ExampleInfo[];
|
|
636
|
+
frontmatter: Record<string, string | string[]>;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Parses a component's Markdown/MDX page into a description, sections and
|
|
640
|
+
* runnable examples. MDX `import`/`export` lines are dropped; JSX in prose is
|
|
641
|
+
* kept as text.
|
|
642
|
+
*/
|
|
643
|
+
export declare function parseDoc(text: string, file: string): ParsedDoc;
|
|
644
|
+
/** Attaches docs and their examples to components. Returns warnings for unmatched pages. */
|
|
645
|
+
export declare function attachDocs(components: ComponentInfo[], docs: ParsedDoc[]): string[];
|
|
646
|
+
//#endregion
|
|
647
|
+
//#region src/catalog.d.ts
|
|
648
|
+
/** One project's design system at a workspace root. */
|
|
649
|
+
interface ServedProject {
|
|
650
|
+
ds: DesignSystem;
|
|
651
|
+
/** Folder relative to the workspace root, with forward slashes. */
|
|
652
|
+
dir: string;
|
|
653
|
+
name?: string | undefined;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* The projects of a workspace root, as the MCP server serves them: one design system per
|
|
657
|
+
* path, and all of them for the merged catalog.
|
|
658
|
+
*/
|
|
659
|
+
interface ProjectSet {
|
|
660
|
+
root: string;
|
|
661
|
+
/** Folders of the projects with a design system, relative to the root. */
|
|
662
|
+
dirs: string[];
|
|
663
|
+
/** The design system that checks `target`, a file or folder relative to the root. */
|
|
664
|
+
forPath(target: string): Promise<ServedProject>;
|
|
665
|
+
/** Every project with a design system, loaded. */
|
|
666
|
+
all(): Promise<ServedProject[]>;
|
|
667
|
+
/** Their components and tokens together, rebuilt when a project reloads. */
|
|
668
|
+
catalog(): Promise<Catalog>;
|
|
669
|
+
}
|
|
670
|
+
/** A component of the merged catalog: one source declaration, whichever projects use it. */
|
|
671
|
+
interface CatalogEntry {
|
|
672
|
+
/** As the first project that has it describes it, with `source.file` relative to the workspace root. */
|
|
673
|
+
component: ComponentInfo;
|
|
674
|
+
/** The design system to render it with (its props, tokens and parts). */
|
|
675
|
+
ds: DesignSystem;
|
|
676
|
+
/** The package its source file belongs to: `@acme/ui`, or the app's own name. */
|
|
677
|
+
package: string;
|
|
678
|
+
/** Folders of the projects that use it. */
|
|
679
|
+
projects: string[];
|
|
680
|
+
/** Another component of the catalog has the same name. */
|
|
681
|
+
ambiguous: boolean;
|
|
682
|
+
}
|
|
683
|
+
interface CatalogToken {
|
|
684
|
+
token: Token;
|
|
685
|
+
ds: DesignSystem;
|
|
686
|
+
package: string;
|
|
687
|
+
projects: string[];
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Every project's components and tokens in one list, for a workspace root when no path
|
|
691
|
+
* picks a project. A component used by several projects (a design-system package) is
|
|
692
|
+
* listed once, tagged with its package; two different components under one name are both
|
|
693
|
+
* listed, each with its package, and a lookup by that name returns both.
|
|
694
|
+
*/
|
|
695
|
+
declare class Catalog {
|
|
696
|
+
readonly root: string;
|
|
697
|
+
readonly projects: ServedProject[];
|
|
698
|
+
readonly entries: CatalogEntry[];
|
|
699
|
+
readonly tokens: CatalogToken[];
|
|
700
|
+
private readonly index;
|
|
701
|
+
constructor(root: string, projects: ServedProject[]);
|
|
702
|
+
/** Top-level components, not parts of another. */
|
|
703
|
+
roots(): CatalogEntry[];
|
|
704
|
+
/** Every distinct component a name resolves to, through each project's lookup. */
|
|
705
|
+
find(name: string): CatalogEntry[];
|
|
706
|
+
suggest(name: string): string | undefined;
|
|
707
|
+
search(query: string, limit?: number): (SearchHit & {
|
|
708
|
+
entry: CatalogEntry;
|
|
709
|
+
})[];
|
|
710
|
+
/** Tokens as `get_tokens` filters them, core ones before scoped families. */
|
|
711
|
+
getTokens(filter?: {
|
|
712
|
+
category?: TokenCategory | undefined;
|
|
713
|
+
query?: string | undefined;
|
|
714
|
+
}): CatalogToken[];
|
|
715
|
+
}
|
|
716
|
+
//#endregion
|
|
717
|
+
//#region src/server/index.d.ts
|
|
718
|
+
export declare const INSTRUCTIONS = "This server describes the project's design system: its React components (props, variants, parts), design tokens and usage docs, and lints UI code against it.\nWhen writing or changing UI in this project:\n1. Find components with search_components (by intent) or list_components.\n2. Read get_component before using a component: use only the props and variant values it lists.\n3. Style with tokens from get_tokens, never with hex/rgb colors, arbitrary px values or Tailwind's default palette.\n4. Run check_ui on every snippet or file you write and fix all errors before you finish.\nIn a monorepo served from its root, pass `path` (the file you are editing) to list_components, get_component, search_components and get_tokens, and `path` or `filename` to check_ui, so each answer comes from that file's own project.";
|
|
719
|
+
interface CreateServerOptions {
|
|
720
|
+
/**
|
|
721
|
+
* Resolves the design system to serve. Called per request, so it can be swapped on reload.
|
|
722
|
+
* `target` is the `path` (or `filename`) the request names, if any, as given.
|
|
723
|
+
*/
|
|
724
|
+
getDesignSystem: (target?: string) => Promise<DesignSystem>;
|
|
725
|
+
/**
|
|
726
|
+
* At a workspace root: its projects. When this resolves to a set, the tools take a `path`
|
|
727
|
+
* to pick a project and serve every project together without one, and `getDesignSystem`
|
|
728
|
+
* is not called. `target` is the `path` (or `filename`) the request names, if any.
|
|
729
|
+
*/
|
|
730
|
+
getProjects?: (target?: string) => Promise<ProjectSet | undefined>;
|
|
731
|
+
}
|
|
732
|
+
/** Builds the MCP server: five tools, two resources and one prompt. Transport-agnostic. */
|
|
733
|
+
export declare function createServer({ getDesignSystem, getProjects }: CreateServerOptions): McpServer;
|
|
734
|
+
//#endregion
|
|
735
|
+
//#region src/server/stdio.d.ts
|
|
736
|
+
interface ServeOptions extends LoadConfigOptions {
|
|
737
|
+
cwd: string;
|
|
738
|
+
cache: boolean;
|
|
739
|
+
watch: boolean;
|
|
740
|
+
logger: Logger;
|
|
741
|
+
/** Defaults to stdio. */
|
|
742
|
+
transport?: Transport;
|
|
743
|
+
}
|
|
744
|
+
/** The running server: `close()` ends the connection and stops watching. */
|
|
745
|
+
interface ServerHandle {
|
|
746
|
+
close(): Promise<void>;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Starts the server (on stdio unless another transport is given), for clients on
|
|
750
|
+
* either protocol era: a 2026-07-28 client (stateless, `server/discover`) and a
|
|
751
|
+
* 2025-era one (the `initialize` handshake) are both served, the era chosen by the
|
|
752
|
+
* client's first message.
|
|
753
|
+
*
|
|
754
|
+
* The project root comes from `--root` or `--config`, a config file in the working
|
|
755
|
+
* directory, or the working directory itself when it holds a project (a
|
|
756
|
+
* package.json, a components.json). MCP roots, which the 2026-07-28 revision
|
|
757
|
+
* deprecates, are the fallback for a 2025-era client that starts servers somewhere
|
|
758
|
+
* else (Claude Desktop starts them in `/`): its first `file://` root. At a monorepo
|
|
759
|
+
* root with no design system of its own, every project in it is served.
|
|
760
|
+
*
|
|
761
|
+
* When none of those gives a project (a client that starts servers in the home or the
|
|
762
|
+
* plugin's folder and reports no roots), each request's project is found from the
|
|
763
|
+
* absolute path it names (`findProjectRoot`): the nearest folder at or above it with a
|
|
764
|
+
* project marker, or the monorepo root above that, served as if the server had been
|
|
765
|
+
* started there, except that a config there is read only when it is JSON: a prompt can
|
|
766
|
+
* choose the path, so a JavaScript or TypeScript config is not run. Each root found is
|
|
767
|
+
* loaded once and kept; a request without an absolute path is answered from the one root
|
|
768
|
+
* found so far.
|
|
769
|
+
*/
|
|
770
|
+
export declare function serveStdio(options: ServeOptions): Promise<ServerHandle>;
|
|
771
|
+
//#endregion
|
|
772
|
+
//#region src/version.d.ts
|
|
773
|
+
export declare const VERSION: string;
|
|
774
|
+
//#endregion
|
|
775
|
+
export { type CheckResult, type ComponentDocs, type ComponentInfo, type CompoundVariantInfo, type Config, type DesignSystemModel, type Diagnostic, type DocSection, type ExampleInfo, type HostOptions, type InheritedProps, type LoadConfigOptions, type LoadOptions, type OutputFormat, type PropInfo, RULE_IDS, type ResolvedConfig, type RuleId, type Severity, type SourceLocation, type TOKEN_CATEGORIES, type TextEdit, type Token, type TokenCategory, type VariantInfo, configJsonSchema, defineConfig, loadConfig };
|