@master/css-mcp 2.0.0-rc.77 → 2.0.0-rc.78
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 +34 -4
- package/dist/bin/index.js +1 -1
- package/dist/classes.d.ts +237 -0
- package/dist/classes.js +224 -0
- package/dist/compare.d.ts +71 -0
- package/dist/compare.js +131 -0
- package/dist/context.js +2 -2
- package/dist/contributor.d.ts +150 -0
- package/dist/contributor.js +497 -0
- package/dist/directives.d.ts +133 -0
- package/dist/directives.js +158 -0
- package/dist/document.d.ts +25 -0
- package/dist/document.js +51 -0
- package/dist/format.d.ts +57 -0
- package/dist/format.js +81 -0
- package/dist/index.d.ts +1 -1
- package/dist/language.js +2 -20
- package/dist/manifest-query.d.ts +149 -0
- package/dist/manifest-query.js +159 -0
- package/dist/manifest-summary.d.ts +48 -0
- package/dist/manifest-summary.js +56 -0
- package/dist/scan.d.ts +1 -1
- package/dist/scan.js +2 -2
- package/dist/server.js +202 -3
- package/dist/setup.d.ts +63 -0
- package/dist/setup.js +168 -0
- package/package.json +11 -9
package/dist/compare.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createMCPTextDocument } from "./document.js";
|
|
2
|
+
import { loadWorkspaceManifest } from "./project.js";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import CSSLanguageService from "@master/css-language-service";
|
|
5
|
+
import { createCSSWithNativeDeclarations } from "@master/css-validator/native-declaration";
|
|
6
|
+
import { parseHTML } from "@master/css-server";
|
|
7
|
+
//#region src/compare.ts
|
|
8
|
+
const CSS_COMPARE_VERSION = 1;
|
|
9
|
+
const defaultManifest = createRequire(import.meta.url)("@master/css-preset/default-manifest.json");
|
|
10
|
+
function unique(values) {
|
|
11
|
+
return [...new Set(values)];
|
|
12
|
+
}
|
|
13
|
+
function splitClassList(value) {
|
|
14
|
+
return unique((value ?? "").split(/\s+/).map((className) => className.trim()).filter(Boolean));
|
|
15
|
+
}
|
|
16
|
+
function extractContentClasses(content, filePath) {
|
|
17
|
+
if (content === void 0) return [];
|
|
18
|
+
const service = new CSSLanguageService();
|
|
19
|
+
const document = createMCPTextDocument(filePath, content);
|
|
20
|
+
return unique(service.getClassPositions(document).map((position) => position.token));
|
|
21
|
+
}
|
|
22
|
+
function resolveClasses(options, side, filePath) {
|
|
23
|
+
const classList = side === "before" ? options.beforeClassList : options.afterClassList;
|
|
24
|
+
const html = side === "before" ? options.beforeHtml : options.afterHtml;
|
|
25
|
+
const content = side === "before" ? options.beforeContent : options.afterContent;
|
|
26
|
+
if (classList !== void 0) return splitClassList(classList);
|
|
27
|
+
if (html !== void 0) return unique(parseHTML(html).classes);
|
|
28
|
+
return extractContentClasses(content, filePath);
|
|
29
|
+
}
|
|
30
|
+
function renderClasses(manifest, classes) {
|
|
31
|
+
const css = createCSSWithNativeDeclarations(manifest);
|
|
32
|
+
const invalid = [];
|
|
33
|
+
for (const className of classes) {
|
|
34
|
+
const rules = css.generate(className);
|
|
35
|
+
if (rules.length) for (const rule of rules) rule.layer.insert(rule);
|
|
36
|
+
else invalid.push(className);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
text: css.text,
|
|
40
|
+
bytes: css.text.length,
|
|
41
|
+
invalid
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function diffValues(before, after) {
|
|
45
|
+
return {
|
|
46
|
+
added: after.filter((value) => !before.includes(value)),
|
|
47
|
+
removed: before.filter((value) => !after.includes(value)),
|
|
48
|
+
unchanged: after.filter((value) => before.includes(value))
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function splitRules(css) {
|
|
52
|
+
return css.split(/(?<=})/).map((rule) => rule.trim()).filter(Boolean);
|
|
53
|
+
}
|
|
54
|
+
function createTextDiff(before, after) {
|
|
55
|
+
if (before === after) return "";
|
|
56
|
+
const beforeLines = before.split("\n");
|
|
57
|
+
const afterLines = after.split("\n");
|
|
58
|
+
return [
|
|
59
|
+
"--- before.css",
|
|
60
|
+
"+++ after.css",
|
|
61
|
+
"@@",
|
|
62
|
+
...beforeLines.map((line) => `-${line}`),
|
|
63
|
+
...afterLines.map((line) => `+${line}`)
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
async function compareCSS(context, options) {
|
|
67
|
+
const manifest = await loadWorkspaceManifest(context);
|
|
68
|
+
const filePath = context.resolveVirtualPath(options.filePath || "index.html");
|
|
69
|
+
const activeManifest = manifest.status === "loaded" ? manifest.manifest : defaultManifest;
|
|
70
|
+
const beforeClasses = resolveClasses(options, "before", filePath);
|
|
71
|
+
const afterClasses = resolveClasses(options, "after", filePath);
|
|
72
|
+
const before = renderClasses(activeManifest, beforeClasses);
|
|
73
|
+
const after = renderClasses(activeManifest, afterClasses);
|
|
74
|
+
const classDiff = diffValues(beforeClasses, afterClasses);
|
|
75
|
+
const ruleDiff = diffValues(splitRules(before.text), splitRules(after.text));
|
|
76
|
+
return {
|
|
77
|
+
version: CSS_COMPARE_VERSION,
|
|
78
|
+
root: context.root,
|
|
79
|
+
manifest: {
|
|
80
|
+
status: manifest.status,
|
|
81
|
+
entries: manifest.entries,
|
|
82
|
+
...manifest.status === "error" ? { error: manifest.error } : {}
|
|
83
|
+
},
|
|
84
|
+
inputs: {
|
|
85
|
+
filePath,
|
|
86
|
+
before: {
|
|
87
|
+
classes: beforeClasses.length,
|
|
88
|
+
invalid: before.invalid.length
|
|
89
|
+
},
|
|
90
|
+
after: {
|
|
91
|
+
classes: afterClasses.length,
|
|
92
|
+
invalid: after.invalid.length
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
classes: classDiff,
|
|
96
|
+
invalid: {
|
|
97
|
+
before: before.invalid,
|
|
98
|
+
after: after.invalid,
|
|
99
|
+
added: after.invalid.filter((className) => !before.invalid.includes(className)),
|
|
100
|
+
removed: before.invalid.filter((className) => !after.invalid.includes(className))
|
|
101
|
+
},
|
|
102
|
+
css: {
|
|
103
|
+
changed: before.text !== after.text,
|
|
104
|
+
before: {
|
|
105
|
+
bytes: before.bytes,
|
|
106
|
+
text: before.text
|
|
107
|
+
},
|
|
108
|
+
after: {
|
|
109
|
+
bytes: after.bytes,
|
|
110
|
+
text: after.text
|
|
111
|
+
},
|
|
112
|
+
bytesDelta: after.bytes - before.bytes,
|
|
113
|
+
diff: createTextDiff(before.text, after.text)
|
|
114
|
+
},
|
|
115
|
+
rules: {
|
|
116
|
+
added: ruleDiff.added,
|
|
117
|
+
removed: ruleDiff.removed,
|
|
118
|
+
unchanged: ruleDiff.unchanged.length
|
|
119
|
+
},
|
|
120
|
+
summary: {
|
|
121
|
+
changed: before.text !== after.text,
|
|
122
|
+
addedClasses: classDiff.added.length,
|
|
123
|
+
removedClasses: classDiff.removed.length,
|
|
124
|
+
addedRules: ruleDiff.added.length,
|
|
125
|
+
removedRules: ruleDiff.removed.length,
|
|
126
|
+
bytesDelta: after.bytes - before.bytes
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
export { compareCSS };
|
package/dist/context.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
-
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
3
1
|
import { mkdir, readFile, realpath, stat, writeFile } from "node:fs/promises";
|
|
4
2
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
4
|
+
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
5
5
|
//#region src/context.ts
|
|
6
6
|
const DEFAULT_PREVIEW_TTL = 300 * 1e3;
|
|
7
7
|
function sha256(text) {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import MasterCSSMCPContext from "./context.js";
|
|
2
|
+
|
|
3
|
+
//#region src/contributor.d.ts
|
|
4
|
+
interface ContributorInput {
|
|
5
|
+
paths?: string[];
|
|
6
|
+
diff?: string;
|
|
7
|
+
task?: string;
|
|
8
|
+
}
|
|
9
|
+
interface PackageGraphInput {
|
|
10
|
+
packageName?: string;
|
|
11
|
+
includeExamples?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface WorkspacePackage {
|
|
14
|
+
name: string;
|
|
15
|
+
path: string;
|
|
16
|
+
private: boolean;
|
|
17
|
+
kind: 'root' | 'package' | 'site' | 'shared' | 'benchmarks' | 'example';
|
|
18
|
+
scripts: string[];
|
|
19
|
+
exports: string[];
|
|
20
|
+
dependencies: string[];
|
|
21
|
+
dependents: string[];
|
|
22
|
+
aiNotes: string | null;
|
|
23
|
+
}
|
|
24
|
+
interface Risk {
|
|
25
|
+
id: string;
|
|
26
|
+
severity: 'info' | 'warning' | 'high';
|
|
27
|
+
reason: string;
|
|
28
|
+
paths: string[];
|
|
29
|
+
}
|
|
30
|
+
declare function getPackageGraph(context: MasterCSSMCPContext, input?: PackageGraphInput): Promise<{
|
|
31
|
+
packages: WorkspacePackage[];
|
|
32
|
+
summary: {
|
|
33
|
+
packages: number;
|
|
34
|
+
workspacePackages: number;
|
|
35
|
+
examples: number;
|
|
36
|
+
};
|
|
37
|
+
status: "loaded" | "limited";
|
|
38
|
+
reason: string;
|
|
39
|
+
version: number;
|
|
40
|
+
audience: string;
|
|
41
|
+
root: string;
|
|
42
|
+
}>;
|
|
43
|
+
declare function getRepoContext(context: MasterCSSMCPContext, input?: ContributorInput): Promise<{
|
|
44
|
+
inputs: {
|
|
45
|
+
task: string | null;
|
|
46
|
+
paths: string[];
|
|
47
|
+
hasDiff: boolean;
|
|
48
|
+
};
|
|
49
|
+
affectedPackages: {
|
|
50
|
+
matchedPaths: string[];
|
|
51
|
+
name: string;
|
|
52
|
+
path: string;
|
|
53
|
+
kind: WorkspacePackage["kind"] | "agent-docs" | "repo-root";
|
|
54
|
+
packageJSON?: string;
|
|
55
|
+
aiNotes?: string | null;
|
|
56
|
+
}[];
|
|
57
|
+
context: {
|
|
58
|
+
files: string[];
|
|
59
|
+
note: string;
|
|
60
|
+
};
|
|
61
|
+
risks: Risk[];
|
|
62
|
+
validation: {
|
|
63
|
+
commands: {
|
|
64
|
+
command: string;
|
|
65
|
+
reason: string;
|
|
66
|
+
}[];
|
|
67
|
+
};
|
|
68
|
+
status: "loaded" | "limited";
|
|
69
|
+
reason: string;
|
|
70
|
+
version: number;
|
|
71
|
+
audience: string;
|
|
72
|
+
root: string;
|
|
73
|
+
} | {
|
|
74
|
+
version: number;
|
|
75
|
+
audience: string;
|
|
76
|
+
root: string;
|
|
77
|
+
status: "error";
|
|
78
|
+
error: string;
|
|
79
|
+
}>;
|
|
80
|
+
declare function getChangeImpact(context: MasterCSSMCPContext, input?: ContributorInput): Promise<{
|
|
81
|
+
version: number;
|
|
82
|
+
audience: string;
|
|
83
|
+
root: string;
|
|
84
|
+
status: "error";
|
|
85
|
+
error: string;
|
|
86
|
+
} | {
|
|
87
|
+
version: number;
|
|
88
|
+
audience: string;
|
|
89
|
+
root: string;
|
|
90
|
+
status: "loaded" | "limited";
|
|
91
|
+
reason: string;
|
|
92
|
+
inputs: {
|
|
93
|
+
task: string | null;
|
|
94
|
+
paths: string[];
|
|
95
|
+
hasDiff: boolean;
|
|
96
|
+
};
|
|
97
|
+
affectedPackages: {
|
|
98
|
+
matchedPaths: string[];
|
|
99
|
+
name: string;
|
|
100
|
+
path: string;
|
|
101
|
+
kind: WorkspacePackage["kind"] | "agent-docs" | "repo-root";
|
|
102
|
+
packageJSON?: string;
|
|
103
|
+
aiNotes?: string | null;
|
|
104
|
+
}[];
|
|
105
|
+
risks: Risk[];
|
|
106
|
+
summary: {
|
|
107
|
+
riskCount: number;
|
|
108
|
+
highRisk: number;
|
|
109
|
+
packageCount: number;
|
|
110
|
+
};
|
|
111
|
+
}>;
|
|
112
|
+
declare function getTestRouter(context: MasterCSSMCPContext, input?: ContributorInput): Promise<{
|
|
113
|
+
version: number;
|
|
114
|
+
audience: string;
|
|
115
|
+
root: string;
|
|
116
|
+
status: "error";
|
|
117
|
+
error: string;
|
|
118
|
+
} | {
|
|
119
|
+
version: number;
|
|
120
|
+
audience: string;
|
|
121
|
+
root: string;
|
|
122
|
+
status: "loaded" | "limited";
|
|
123
|
+
reason: string;
|
|
124
|
+
inputs: {
|
|
125
|
+
task: string | null;
|
|
126
|
+
paths: string[];
|
|
127
|
+
hasDiff: boolean;
|
|
128
|
+
};
|
|
129
|
+
affectedPackages: {
|
|
130
|
+
matchedPaths: string[];
|
|
131
|
+
name: string;
|
|
132
|
+
path: string;
|
|
133
|
+
kind: WorkspacePackage["kind"] | "agent-docs" | "repo-root";
|
|
134
|
+
packageJSON?: string;
|
|
135
|
+
aiNotes?: string | null;
|
|
136
|
+
}[];
|
|
137
|
+
validation: {
|
|
138
|
+
commands: {
|
|
139
|
+
command: string;
|
|
140
|
+
reason: string;
|
|
141
|
+
}[];
|
|
142
|
+
};
|
|
143
|
+
risks: {
|
|
144
|
+
id: string;
|
|
145
|
+
severity: "info" | "warning" | "high";
|
|
146
|
+
reason: string;
|
|
147
|
+
}[];
|
|
148
|
+
}>;
|
|
149
|
+
//#endregion
|
|
150
|
+
export { ContributorInput, PackageGraphInput, getChangeImpact, getPackageGraph, getRepoContext, getTestRouter };
|