@lyse-labs/lyse 0.1.0-alpha.2 → 0.2.0-alpha.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/LICENSE +0 -5
- package/dist/cli.js +67 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/add-ci-gate.test.d.ts +1 -0
- package/dist/commands/__tests__/add-ci-gate.test.js +149 -0
- package/dist/commands/__tests__/add-ci-gate.test.js.map +1 -0
- package/dist/commands/add-ci-gate.d.ts +26 -0
- package/dist/commands/add-ci-gate.js +429 -0
- package/dist/commands/add-ci-gate.js.map +1 -0
- package/dist/commands/audit-pipeline.js +1 -1
- package/dist/commands/audit-pipeline.js.map +1 -1
- package/dist/commands/fix.d.ts +8 -8
- package/dist/commands/init.d.ts +3 -3
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp-setup.js +1 -1
- package/dist/commands/mcp-setup.js.map +1 -1
- package/dist/config/schema.d.ts +14 -14
- package/dist/llm/__tests__/layer4-stage.test.d.ts +1 -0
- package/dist/llm/__tests__/layer4-stage.test.js +157 -0
- package/dist/llm/__tests__/layer4-stage.test.js.map +1 -0
- package/dist/llm/__tests__/validator.test.d.ts +1 -0
- package/dist/llm/__tests__/validator.test.js +156 -0
- package/dist/llm/__tests__/validator.test.js.map +1 -0
- package/dist/llm/connectors/__tests__/anthropic-adapter.test.d.ts +1 -0
- package/dist/llm/connectors/__tests__/anthropic-adapter.test.js +99 -0
- package/dist/llm/connectors/__tests__/anthropic-adapter.test.js.map +1 -0
- package/dist/llm/connectors/__tests__/cache.test.d.ts +1 -0
- package/dist/llm/connectors/__tests__/cache.test.js +50 -0
- package/dist/llm/connectors/__tests__/cache.test.js.map +1 -0
- package/dist/llm/connectors/__tests__/noop-adapter.test.d.ts +1 -0
- package/dist/llm/connectors/__tests__/noop-adapter.test.js +21 -0
- package/dist/llm/connectors/__tests__/noop-adapter.test.js.map +1 -0
- package/dist/llm/connectors/__tests__/openai-compatible-adapter.test.d.ts +1 -0
- package/dist/llm/connectors/__tests__/openai-compatible-adapter.test.js +82 -0
- package/dist/llm/connectors/__tests__/openai-compatible-adapter.test.js.map +1 -0
- package/dist/llm/connectors/__tests__/resolver.test.d.ts +1 -0
- package/dist/llm/connectors/__tests__/resolver.test.js +140 -0
- package/dist/llm/connectors/__tests__/resolver.test.js.map +1 -0
- package/dist/llm/connectors/anthropic-adapter.d.ts +12 -0
- package/dist/llm/connectors/anthropic-adapter.js +57 -0
- package/dist/llm/connectors/anthropic-adapter.js.map +1 -0
- package/dist/llm/connectors/cache.d.ts +15 -0
- package/dist/llm/connectors/cache.js +57 -0
- package/dist/llm/connectors/cache.js.map +1 -0
- package/dist/llm/connectors/noop-adapter.d.ts +4 -0
- package/dist/llm/connectors/noop-adapter.js +12 -0
- package/dist/llm/connectors/noop-adapter.js.map +1 -0
- package/dist/llm/connectors/openai-compatible-adapter.d.ts +13 -0
- package/dist/llm/connectors/openai-compatible-adapter.js +47 -0
- package/dist/llm/connectors/openai-compatible-adapter.js.map +1 -0
- package/dist/llm/connectors/resolver.d.ts +9 -0
- package/dist/llm/connectors/resolver.js +162 -0
- package/dist/llm/connectors/resolver.js.map +1 -0
- package/dist/llm/connectors/types.d.ts +25 -0
- package/dist/llm/connectors/types.js +13 -0
- package/dist/llm/connectors/types.js.map +1 -0
- package/dist/llm/layer4-stage.d.ts +8 -6
- package/dist/llm/layer4-stage.js +145 -9
- package/dist/llm/layer4-stage.js.map +1 -1
- package/dist/llm/rubric-stub.d.ts +8 -0
- package/dist/llm/rubric-stub.js +4 -0
- package/dist/llm/rubric-stub.js.map +1 -0
- package/dist/llm/validator.d.ts +18 -0
- package/dist/llm/validator.js +81 -0
- package/dist/llm/validator.js.map +1 -0
- package/dist/parsers/ai-tokens.d.ts +10 -0
- package/dist/parsers/ai-tokens.js +156 -0
- package/dist/parsers/ai-tokens.js.map +1 -0
- package/dist/reliability/catalogue/__tests__/sub-axes.test.js +13 -3
- package/dist/reliability/catalogue/__tests__/sub-axes.test.js.map +1 -1
- package/dist/reliability/catalogue/sub-axes.js +16 -0
- package/dist/reliability/catalogue/sub-axes.js.map +1 -1
- package/dist/reliability/types.d.ts +1 -1
- package/dist/rule-runner.js +1 -1
- package/dist/rule-runner.js.map +1 -1
- package/dist/rules/ai-governance-ai-content-live-region.d.ts +11 -0
- package/dist/rules/ai-governance-ai-content-live-region.js +304 -0
- package/dist/rules/ai-governance-ai-content-live-region.js.map +1 -0
- package/dist/rules/ai-governance-ai-loading-error-states.d.ts +9 -0
- package/dist/rules/ai-governance-ai-loading-error-states.js +214 -0
- package/dist/rules/ai-governance-ai-loading-error-states.js.map +1 -0
- package/dist/rules/ai-governance-ai-marker-anti-patterns.d.ts +15 -0
- package/dist/rules/ai-governance-ai-marker-anti-patterns.js +178 -0
- package/dist/rules/ai-governance-ai-marker-anti-patterns.js.map +1 -0
- package/dist/rules/ai-governance-ai-marker-component-present.d.ts +28 -0
- package/dist/rules/ai-governance-ai-marker-component-present.js +320 -0
- package/dist/rules/ai-governance-ai-marker-component-present.js.map +1 -0
- package/dist/rules/ai-governance-ai-token-requires-marker.d.ts +17 -0
- package/dist/rules/ai-governance-ai-token-requires-marker.js +206 -0
- package/dist/rules/ai-governance-ai-token-requires-marker.js.map +1 -0
- package/dist/rules/ai-governance-ai-tokens-reserved.d.ts +8 -0
- package/dist/rules/ai-governance-ai-tokens-reserved.js +85 -0
- package/dist/rules/ai-governance-ai-tokens-reserved.js.map +1 -0
- package/dist/rules/ai-governance-disclaimer-present.d.ts +18 -0
- package/dist/rules/ai-governance-disclaimer-present.js +210 -0
- package/dist/rules/ai-governance-disclaimer-present.js.map +1 -0
- package/dist/rules/ai-governance-explainability-affordance.d.ts +14 -0
- package/dist/rules/ai-governance-explainability-affordance.js +196 -0
- package/dist/rules/ai-governance-explainability-affordance.js.map +1 -0
- package/dist/rules/ai-governance-feedback-control-present.d.ts +19 -0
- package/dist/rules/ai-governance-feedback-control-present.js +223 -0
- package/dist/rules/ai-governance-feedback-control-present.js.map +1 -0
- package/dist/rules/ai-governance-human-control-affordances.d.ts +16 -0
- package/dist/rules/ai-governance-human-control-affordances.js +228 -0
- package/dist/rules/ai-governance-human-control-affordances.js.map +1 -0
- package/dist/rules/ai-governance-value-gate-doc-present.d.ts +18 -0
- package/dist/rules/ai-governance-value-gate-doc-present.js +206 -0
- package/dist/rules/ai-governance-value-gate-doc-present.js.map +1 -0
- package/dist/rules/ai-surface-agent-instruction-files.d.ts +33 -0
- package/dist/rules/ai-surface-agent-instruction-files.js +310 -0
- package/dist/rules/ai-surface-agent-instruction-files.js.map +1 -0
- package/dist/rules/ai-surface-llms-txt-structure.d.ts +18 -0
- package/dist/rules/ai-surface-llms-txt-structure.js +200 -0
- package/dist/rules/ai-surface-llms-txt-structure.js.map +1 -0
- package/dist/rules/ai-surface-mcp-config-present.d.ts +23 -0
- package/dist/rules/ai-surface-mcp-config-present.js +193 -0
- package/dist/rules/ai-surface-mcp-config-present.js.map +1 -0
- package/dist/rules/ai-surface-shadcn-registry-valid.d.ts +22 -0
- package/dist/rules/ai-surface-shadcn-registry-valid.js +247 -0
- package/dist/rules/ai-surface-shadcn-registry-valid.js.map +1 -0
- package/dist/rules/components-contracts-strictness.d.ts +48 -0
- package/dist/rules/components-contracts-strictness.js +372 -0
- package/dist/rules/components-contracts-strictness.js.map +1 -0
- package/dist/rules/registry.js +32 -0
- package/dist/rules/registry.js.map +1 -1
- package/dist/rules/tokens-dtcg-conformance.d.ts +55 -19
- package/dist/rules/tokens-dtcg-conformance.js +320 -82
- package/dist/rules/tokens-dtcg-conformance.js.map +1 -1
- package/dist/scorer.js +4 -3
- package/dist/scorer.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js.map +1 -1
- package/package.json +41 -16
- package/rules-manifest.json +431 -6
- package/schemas/v1/lyse-rules.json +1 -1
- package/dist/commands/ci-setup.d.ts +0 -9
- package/dist/commands/ci-setup.js +0 -42
- package/dist/commands/ci-setup.js.map +0 -1
- package/dist/commands/templates/lyse-workflow.yml.template +0 -30
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import fg from "fast-glob";
|
|
4
|
+
import { isPathExcluded } from "./_exclude.js";
|
|
5
|
+
import { createLyseRule } from "./_rule-module.js";
|
|
6
|
+
const RULE_ID = "ai-surface/shadcn-registry-valid";
|
|
7
|
+
const MAX_FILE_BYTES = 4_000_000;
|
|
8
|
+
const SHADCN_MARKER = "components.json";
|
|
9
|
+
const REGISTRY_CANDIDATES = [
|
|
10
|
+
"registry.json",
|
|
11
|
+
"public/registry.json",
|
|
12
|
+
"registry/*.json",
|
|
13
|
+
];
|
|
14
|
+
function discoverRegistryFiles(ctx) {
|
|
15
|
+
if (!ctx.repoRoot)
|
|
16
|
+
return [];
|
|
17
|
+
let entries = [];
|
|
18
|
+
try {
|
|
19
|
+
entries = fg.sync(REGISTRY_CANDIDATES, {
|
|
20
|
+
cwd: ctx.repoRoot,
|
|
21
|
+
absolute: false,
|
|
22
|
+
dot: false,
|
|
23
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.git/**"],
|
|
24
|
+
followSymbolicLinks: false,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const out = new Set();
|
|
31
|
+
for (const rel of entries) {
|
|
32
|
+
if (isPathExcluded(rel, ctx.excludePaths))
|
|
33
|
+
continue;
|
|
34
|
+
out.add(rel);
|
|
35
|
+
}
|
|
36
|
+
return Array.from(out).sort();
|
|
37
|
+
}
|
|
38
|
+
function readJsonIfSmall(absPath) {
|
|
39
|
+
try {
|
|
40
|
+
const stat = statSync(absPath);
|
|
41
|
+
if (!stat.isFile())
|
|
42
|
+
return { data: null, parseError: null };
|
|
43
|
+
if (stat.size > MAX_FILE_BYTES)
|
|
44
|
+
return { data: null, parseError: "file too large" };
|
|
45
|
+
const raw = readFileSync(absPath, "utf8");
|
|
46
|
+
if (raw.trim().length === 0)
|
|
47
|
+
return { data: null, parseError: "empty file" };
|
|
48
|
+
return { data: JSON.parse(raw), parseError: null };
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return { data: null, parseError: e instanceof Error ? e.message : "unknown parse error" };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function hasShadcnMarker(repoRoot) {
|
|
55
|
+
return existsSync(join(repoRoot, SHADCN_MARKER));
|
|
56
|
+
}
|
|
57
|
+
function validateRegistryItem(item) {
|
|
58
|
+
const reasons = [];
|
|
59
|
+
if (typeof item !== "object" || item === null) {
|
|
60
|
+
return { ok: false, reasons: ["registry item is not a JSON object"] };
|
|
61
|
+
}
|
|
62
|
+
const r = item;
|
|
63
|
+
if (typeof r.name !== "string" || r.name.trim().length === 0) {
|
|
64
|
+
reasons.push("missing or empty `name` (required, string)");
|
|
65
|
+
}
|
|
66
|
+
if (typeof r.type !== "string" || r.type.trim().length === 0) {
|
|
67
|
+
reasons.push("missing or empty `type` (required, e.g. \"registry:ui\")");
|
|
68
|
+
}
|
|
69
|
+
// Note: we don't gate on a fixed `VALID_ITEM_TYPES` set — the shadcn schema
|
|
70
|
+
// has evolved over time and accepts arbitrary `registry:*` namespaces, so
|
|
71
|
+
// checking against a hardcoded list produces false positives on legitimate
|
|
72
|
+
// custom types. We just require a non-empty string.
|
|
73
|
+
if (!Array.isArray(r.files)) {
|
|
74
|
+
reasons.push("missing `files` (required, non-empty array of `{ path, content?, type? }`)");
|
|
75
|
+
}
|
|
76
|
+
else if (r.files.length === 0) {
|
|
77
|
+
reasons.push("`files` is empty (must contain at least one `{ path }` entry)");
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
for (let i = 0; i < r.files.length; i++) {
|
|
81
|
+
const f = r.files[i];
|
|
82
|
+
if (typeof f !== "object" || f === null) {
|
|
83
|
+
reasons.push(`files[${i}] is not an object`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const fe = f;
|
|
87
|
+
if (typeof fe.path !== "string" || fe.path.trim().length === 0) {
|
|
88
|
+
reasons.push(`files[${i}] missing \`path\` (required, string)`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { ok: reasons.length === 0, reasons };
|
|
93
|
+
}
|
|
94
|
+
function looksLikeRegistryItem(data) {
|
|
95
|
+
if (typeof data !== "object" || data === null)
|
|
96
|
+
return false;
|
|
97
|
+
const r = data;
|
|
98
|
+
return "name" in r || "type" in r || "files" in r;
|
|
99
|
+
}
|
|
100
|
+
function looksLikeRegistryCollection(data) {
|
|
101
|
+
if (typeof data !== "object" || data === null)
|
|
102
|
+
return false;
|
|
103
|
+
const r = data;
|
|
104
|
+
if (Array.isArray(r.items))
|
|
105
|
+
return true;
|
|
106
|
+
if (Array.isArray(r.registry))
|
|
107
|
+
return true;
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
function extractRegistryItems(data) {
|
|
111
|
+
if (looksLikeRegistryCollection(data)) {
|
|
112
|
+
const r = data;
|
|
113
|
+
const arr = (Array.isArray(r.items) ? r.items : r.registry);
|
|
114
|
+
return { items: arr, shape: "collection" };
|
|
115
|
+
}
|
|
116
|
+
return { items: [data], shape: "single" };
|
|
117
|
+
}
|
|
118
|
+
const evaluate = async (ctx, _files) => {
|
|
119
|
+
const findings = [];
|
|
120
|
+
if (!ctx.repoRoot) {
|
|
121
|
+
return { findings, opportunities: 0 };
|
|
122
|
+
}
|
|
123
|
+
const registryFiles = discoverRegistryFiles(ctx);
|
|
124
|
+
const shadcnMarker = hasShadcnMarker(ctx.repoRoot);
|
|
125
|
+
if (registryFiles.length === 0) {
|
|
126
|
+
if (!shadcnMarker) {
|
|
127
|
+
return { findings, opportunities: 0 };
|
|
128
|
+
}
|
|
129
|
+
findings.push({
|
|
130
|
+
ruleId: RULE_ID,
|
|
131
|
+
axis: "ai-surface",
|
|
132
|
+
severity: "warning",
|
|
133
|
+
location: { file: SHADCN_MARKER, line: 1, column: 1 },
|
|
134
|
+
message: "components.json found but no shadcn registry — missed AI-Consumable surface",
|
|
135
|
+
suggestion: "publish a `registry.json` (or `public/registry.json`) describing your components so AI agents and the shadcn CLI can install them",
|
|
136
|
+
});
|
|
137
|
+
return { findings, opportunities: 1 };
|
|
138
|
+
}
|
|
139
|
+
let opportunities = 0;
|
|
140
|
+
for (const rel of registryFiles) {
|
|
141
|
+
opportunities += 1;
|
|
142
|
+
const abs = join(ctx.repoRoot, rel);
|
|
143
|
+
const { data, parseError } = readJsonIfSmall(abs);
|
|
144
|
+
const relPath = relative(ctx.repoRoot, abs) || rel;
|
|
145
|
+
if (data === null) {
|
|
146
|
+
if (parseError === "file too large") {
|
|
147
|
+
// Per doc: files larger than 4 MB are silently skipped.
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
findings.push({
|
|
151
|
+
ruleId: RULE_ID,
|
|
152
|
+
axis: "ai-surface",
|
|
153
|
+
severity: "error",
|
|
154
|
+
location: { file: relPath, line: 1, column: 1 },
|
|
155
|
+
message: `shadcn registry ${relPath} is not valid JSON${parseError ? ` (${parseError})` : ""}`,
|
|
156
|
+
suggestion: "ensure the registry file is parseable JSON",
|
|
157
|
+
});
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (!looksLikeRegistryItem(data) && !looksLikeRegistryCollection(data)) {
|
|
161
|
+
findings.push({
|
|
162
|
+
ruleId: RULE_ID,
|
|
163
|
+
axis: "ai-surface",
|
|
164
|
+
severity: "error",
|
|
165
|
+
location: { file: relPath, line: 1, column: 1 },
|
|
166
|
+
message: `shadcn registry ${relPath} has no \`name\`/\`type\`/\`files\` at the root and no \`items\` collection`,
|
|
167
|
+
suggestion: "each registry entry must be `{ name, type, files: [{ path, ... }] }` per https://ui.shadcn.com/docs/registry",
|
|
168
|
+
});
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const parsed = extractRegistryItems(data);
|
|
172
|
+
if (parsed.items.length === 0) {
|
|
173
|
+
findings.push({
|
|
174
|
+
ruleId: RULE_ID,
|
|
175
|
+
axis: "ai-surface",
|
|
176
|
+
severity: "error",
|
|
177
|
+
location: { file: relPath, line: 1, column: 1 },
|
|
178
|
+
message: `shadcn registry ${relPath} contains no items`,
|
|
179
|
+
suggestion: "add at least one `{ name, type, files }` entry",
|
|
180
|
+
});
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
for (let i = 0; i < parsed.items.length; i++) {
|
|
184
|
+
const item = parsed.items[i];
|
|
185
|
+
const validation = validateRegistryItem(item);
|
|
186
|
+
if (validation.ok)
|
|
187
|
+
continue;
|
|
188
|
+
const label = parsed.shape === "collection"
|
|
189
|
+
? `items[${i}]`
|
|
190
|
+
: (typeof item?.name === "string" ? `"${item.name}"` : "registry item");
|
|
191
|
+
for (const reason of validation.reasons) {
|
|
192
|
+
findings.push({
|
|
193
|
+
ruleId: RULE_ID,
|
|
194
|
+
axis: "ai-surface",
|
|
195
|
+
severity: "error",
|
|
196
|
+
location: { file: relPath, line: 1, column: 1 },
|
|
197
|
+
message: `shadcn registry ${relPath} ${label}: ${reason}`,
|
|
198
|
+
suggestion: "each entry must include `name` (string), `type` (e.g. \"registry:ui\") and a non-empty `files` array of `{ path }`",
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return { findings, opportunities };
|
|
204
|
+
};
|
|
205
|
+
export const rule = createLyseRule({
|
|
206
|
+
meta: {
|
|
207
|
+
axis: "ai-surface",
|
|
208
|
+
lyseRuleId: RULE_ID,
|
|
209
|
+
defaultSeverity: "warning",
|
|
210
|
+
shortDescription: "shadcn-style registry.json must be present and valid",
|
|
211
|
+
fullDescription: "Detects whether the design system ships a shadcn-style component registry — `registry.json` at the repo root, `public/registry.json` (Next.js-hosted), or per-component `registry/*.json` files. Validates the minimal shadcn shape: each item must have `name` (string), `type` (e.g. \"registry:ui\") and a non-empty `files` array of `{ path, content?, type? }`. Optional fields (`dependencies`, `registryDependencies`, `tailwind`, `cssVars`) are not validated. When `components.json` exists but no registry is shipped, emits a warning for the missed AI-Consumable surface; malformed JSON or missing required fields are errors.",
|
|
212
|
+
helpUri: "https://github.com/lyse-labs/lyse/blob/main/docs/rules/ai-surface-shadcn-registry-valid.md",
|
|
213
|
+
rationale: `Why it matters
|
|
214
|
+
|
|
215
|
+
A valid shadcn-style \`registry.json\` is the single most reliable signal that a design system is AI-Consumable today. The shadcn CLI uses it to install components into downstream apps; coding agents (Cursor, Claude, GPT) increasingly look for it to discover and pull components instead of scraping source files.
|
|
216
|
+
|
|
217
|
+
Detection is conservative — we look for the canonical locations only (\`registry.json\`, \`public/registry.json\`, \`registry/*.json\`) and validate only the three required fields per the public shadcn schema. Optional fields like \`tailwind\` and \`cssVars\` vary across versions and are not part of the validity contract.
|
|
218
|
+
|
|
219
|
+
A repo declaring \`components.json\` (the shadcn CLI marker) but no registry is a strong indicator the team is on the shadcn path but hasn't published the consumable surface — that's a warning, not an error. Malformed JSON or items missing \`name\`/\`type\`/\`files\` will silently break the shadcn CLI and any agent consumer, so they are errors.`,
|
|
220
|
+
examples: [
|
|
221
|
+
{
|
|
222
|
+
good: '{ "name": "button", "type": "registry:ui", "files": [{ "path": "ui/button.tsx" }] }',
|
|
223
|
+
bad: '{ "name": "button", "type": "registry:ui" }',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
good: '{ "items": [{ "name": "button", "type": "registry:ui", "files": [{ "path": "ui/button.tsx" }] }] }',
|
|
227
|
+
bad: '{ "items": [{ "name": "button" }] }',
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
allowlist: [
|
|
231
|
+
"repos with no `components.json` AND no `registry.json` — rule is N/A",
|
|
232
|
+
"files larger than 4 MB — skipped to avoid pathological cases",
|
|
233
|
+
"files matching `ctx.excludePaths` config",
|
|
234
|
+
"disable in `.lyse.yaml`: `rules: { ai-surface/shadcn-registry-valid: off }`",
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
defaultOptions: [],
|
|
238
|
+
create: () => ({ evaluate }),
|
|
239
|
+
});
|
|
240
|
+
export const _internal = {
|
|
241
|
+
validateRegistryItem,
|
|
242
|
+
looksLikeRegistryItem,
|
|
243
|
+
looksLikeRegistryCollection,
|
|
244
|
+
extractRegistryItems,
|
|
245
|
+
REGISTRY_CANDIDATES,
|
|
246
|
+
};
|
|
247
|
+
//# sourceMappingURL=ai-surface-shadcn-registry-valid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-surface-shadcn-registry-valid.js","sourceRoot":"","sources":["../../src/rules/ai-surface-shadcn-registry-valid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Rule } from "../types.js";
|
|
2
|
+
interface ComponentPropFinding {
|
|
3
|
+
componentName: string;
|
|
4
|
+
propName: string;
|
|
5
|
+
kind: "any" | "unknown" | "string-variant";
|
|
6
|
+
line: number;
|
|
7
|
+
column: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Walk a parsed .tsx/.jsx source for exported PascalCase component declarations
|
|
11
|
+
* and collect their typed prop violations.
|
|
12
|
+
*
|
|
13
|
+
* Resolves prop type references to same-file interface / type-alias declarations.
|
|
14
|
+
* Cross-file references are skipped (v0.1 limitation, mirrors loaders/components.ts).
|
|
15
|
+
*/
|
|
16
|
+
export declare function scanComponentContracts(source: string): {
|
|
17
|
+
findings: ComponentPropFinding[];
|
|
18
|
+
componentCount: number;
|
|
19
|
+
};
|
|
20
|
+
interface PackageJsonShape {
|
|
21
|
+
name?: unknown;
|
|
22
|
+
private?: unknown;
|
|
23
|
+
types?: unknown;
|
|
24
|
+
typings?: unknown;
|
|
25
|
+
main?: unknown;
|
|
26
|
+
module?: unknown;
|
|
27
|
+
exports?: unknown;
|
|
28
|
+
}
|
|
29
|
+
type PackageCheckOutcome = {
|
|
30
|
+
kind: "missing-types";
|
|
31
|
+
} | {
|
|
32
|
+
kind: "types-points-to-missing-file";
|
|
33
|
+
typesPath: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "ok";
|
|
36
|
+
typesPath: string;
|
|
37
|
+
};
|
|
38
|
+
export declare function checkPackageJsonTypes(pkg: PackageJsonShape, packageDir: string): PackageCheckOutcome;
|
|
39
|
+
declare function looksLikePublishablePackage(pkg: PackageJsonShape): boolean;
|
|
40
|
+
export declare const rule: Rule;
|
|
41
|
+
export declare const _internal: {
|
|
42
|
+
scanComponentContracts: typeof scanComponentContracts;
|
|
43
|
+
checkPackageJsonTypes: typeof checkPackageJsonTypes;
|
|
44
|
+
looksLikePublishablePackage: typeof looksLikePublishablePackage;
|
|
45
|
+
VARIANT_PROP_RE: RegExp;
|
|
46
|
+
FRAMEWORK_ALLOWED_PROPS: Set<string>;
|
|
47
|
+
};
|
|
48
|
+
export {};
|