@cobwds/mcp-server 1.19.3 → 1.23.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 +6 -15
- package/data/cem/custom-elements.json +10084 -6696
- package/data/frameworks.json +14 -0
- package/data/guides/form-validation.md +1 -1
- package/data/guides/frameworks/angular.md +184 -26
- package/data/guides/frameworks/react-additions.md +69 -0
- package/data/guides/frameworks/react.md +209 -27
- package/data/guides/frameworks/vue.md +356 -0
- package/data/tokens/tokens.css +45 -56
- package/data/tokens/tokens.json +39 -78
- package/dist/index.js +0 -0
- package/dist/lib/cem-parser.d.ts +12 -0
- package/dist/lib/cem-parser.d.ts.map +1 -1
- package/dist/lib/framework-snippets.d.ts +36 -0
- package/dist/lib/framework-snippets.d.ts.map +1 -0
- package/dist/lib/framework-snippets.js +55 -0
- package/dist/lib/framework-usage.d.ts +20 -0
- package/dist/lib/framework-usage.d.ts.map +1 -0
- package/dist/lib/framework-usage.js +50 -0
- package/dist/lib/frameworks-data.d.ts +19 -0
- package/dist/lib/frameworks-data.d.ts.map +1 -0
- package/dist/lib/frameworks-data.js +40 -0
- package/dist/resources/frameworks.d.ts +15 -0
- package/dist/resources/frameworks.d.ts.map +1 -0
- package/dist/resources/frameworks.js +104 -0
- package/dist/resources/guides.d.ts.map +1 -1
- package/dist/resources/guides.js +12 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +2 -0
- package/dist/tools/component-tools.d.ts.map +1 -1
- package/dist/tools/component-tools.js +20 -5
- package/dist/tools/guide-tools.js +1 -1
- package/dist/tools/utility-tools.d.ts +48 -0
- package/dist/tools/utility-tools.d.ts.map +1 -1
- package/dist/tools/utility-tools.js +236 -71
- package/package.json +6 -4
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Resources
|
|
3
|
+
*
|
|
4
|
+
* MCP resources for COBWDS framework packages (@cobwds/react, @cobwds/vue,
|
|
5
|
+
* @cobwds/angular).
|
|
6
|
+
*
|
|
7
|
+
* Resources:
|
|
8
|
+
* - cobwds://frameworks - Index of framework packages with version and guide URI
|
|
9
|
+
* - cobwds://frameworks/react - @cobwds/react guide (synced from its README)
|
|
10
|
+
* - cobwds://frameworks/vue - @cobwds/vue guide (synced from its README)
|
|
11
|
+
* - cobwds://frameworks/angular - @cobwds/angular guide (synced from its README)
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync } from "node:fs";
|
|
14
|
+
import { join, dirname } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { getFrameworksIndex } from "../lib/frameworks-data.js";
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = dirname(__filename);
|
|
19
|
+
const GUIDES_DIR = join(__dirname, "../../data/guides/frameworks");
|
|
20
|
+
function loadFrameworkGuide(framework) {
|
|
21
|
+
try {
|
|
22
|
+
return readFileSync(join(GUIDES_DIR, `${framework}.md`), "utf-8");
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return `Framework guide not found: ${framework}. Run "npm run sync:guides -w @cobwds/mcp-server".`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function registerFrameworkResources(server) {
|
|
29
|
+
// cobwds://frameworks - Index of framework packages
|
|
30
|
+
server.resource("frameworks", "cobwds://frameworks", {
|
|
31
|
+
description: "Index of COBWDS framework packages (@cobwds/react, @cobwds/vue, @cobwds/angular) with their published version and guide resource URI",
|
|
32
|
+
mimeType: "application/json",
|
|
33
|
+
}, async () => {
|
|
34
|
+
const index = getFrameworksIndex();
|
|
35
|
+
const list = [
|
|
36
|
+
{
|
|
37
|
+
id: "react",
|
|
38
|
+
packageName: index.react.packageName,
|
|
39
|
+
version: index.react.version,
|
|
40
|
+
guideUri: "cobwds://frameworks/react",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "vue",
|
|
44
|
+
packageName: index.vue.packageName,
|
|
45
|
+
version: index.vue.version,
|
|
46
|
+
guideUri: "cobwds://frameworks/vue",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "angular",
|
|
50
|
+
packageName: index.angular.packageName,
|
|
51
|
+
version: index.angular.version,
|
|
52
|
+
guideUri: "cobwds://frameworks/angular",
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
return {
|
|
56
|
+
contents: [
|
|
57
|
+
{
|
|
58
|
+
uri: "cobwds://frameworks",
|
|
59
|
+
mimeType: "application/json",
|
|
60
|
+
text: JSON.stringify(list, null, 2),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
// cobwds://frameworks/react - @cobwds/react guide
|
|
66
|
+
server.resource("frameworks-react", "cobwds://frameworks/react", {
|
|
67
|
+
description: "@cobwds/react install, usage, forms, SSR, and troubleshooting guide",
|
|
68
|
+
mimeType: "text/markdown",
|
|
69
|
+
}, async () => ({
|
|
70
|
+
contents: [
|
|
71
|
+
{
|
|
72
|
+
uri: "cobwds://frameworks/react",
|
|
73
|
+
mimeType: "text/markdown",
|
|
74
|
+
text: loadFrameworkGuide("react"),
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
}));
|
|
78
|
+
// cobwds://frameworks/vue - @cobwds/vue guide
|
|
79
|
+
server.resource("frameworks-vue", "cobwds://frameworks/vue", {
|
|
80
|
+
description: "@cobwds/vue install, usage, v-model forms, SSR, and troubleshooting guide",
|
|
81
|
+
mimeType: "text/markdown",
|
|
82
|
+
}, async () => ({
|
|
83
|
+
contents: [
|
|
84
|
+
{
|
|
85
|
+
uri: "cobwds://frameworks/vue",
|
|
86
|
+
mimeType: "text/markdown",
|
|
87
|
+
text: loadFrameworkGuide("vue"),
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
}));
|
|
91
|
+
// cobwds://frameworks/angular - @cobwds/angular guide
|
|
92
|
+
server.resource("frameworks-angular", "cobwds://frameworks/angular", {
|
|
93
|
+
description: "@cobwds/angular install, usage, forms, SSR, and troubleshooting guide",
|
|
94
|
+
mimeType: "text/markdown",
|
|
95
|
+
}, async () => ({
|
|
96
|
+
contents: [
|
|
97
|
+
{
|
|
98
|
+
uri: "cobwds://frameworks/angular",
|
|
99
|
+
mimeType: "text/markdown",
|
|
100
|
+
text: loadFrameworkGuide("angular"),
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../src/resources/guides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"guides.d.ts","sourceRoot":"","sources":["../../src/resources/guides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoF9D"}
|
package/dist/resources/guides.js
CHANGED
|
@@ -56,7 +56,18 @@ Then use them in HTML:
|
|
|
56
56
|
|
|
57
57
|
## Framework Integration
|
|
58
58
|
|
|
59
|
-
For framework-specific setup, use the \`get_guide\` tool with \`topic
|
|
59
|
+
For framework-specific setup, use the \`get_guide\` tool with a \`topic\` and a \`framework\` parameter (angular, react, vue, dotnet, drupal, or vanilla).
|
|
60
|
+
|
|
61
|
+
React, Vue, and Angular are first-class packages, not wrapper snippets:
|
|
62
|
+
\`@cobwds/react\` (\`npm install @cobwds/react\`), \`@cobwds/vue\`
|
|
63
|
+
(\`npm install @cobwds/vue\`), and \`@cobwds/angular\`
|
|
64
|
+
(\`npm install @cobwds/angular @cobwds/components\`) generate typed
|
|
65
|
+
components, props, and events directly from this design system's
|
|
66
|
+
manifest. See the \`cobwds://frameworks\` resource for their current
|
|
67
|
+
published versions, \`cobwds://frameworks/react\`, \`cobwds://frameworks/vue\`, and
|
|
68
|
+
\`cobwds://frameworks/angular\` for their full guides, and pass
|
|
69
|
+
\`framework: "react"\` or \`"angular"\` to \`get_component\` for
|
|
70
|
+
per-component import lines and framework-specific code examples.
|
|
60
71
|
|
|
61
72
|
## Resources
|
|
62
73
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAKzD"}
|
package/dist/resources/index.js
CHANGED
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
import { registerComponentResources } from "./components.js";
|
|
7
7
|
import { registerTokenResources } from "./tokens.js";
|
|
8
8
|
import { registerGuideResources } from "./guides.js";
|
|
9
|
+
import { registerFrameworkResources } from "./frameworks.js";
|
|
9
10
|
export function registerResources(server) {
|
|
10
11
|
registerComponentResources(server);
|
|
11
12
|
registerTokenResources(server);
|
|
12
13
|
registerGuideResources(server);
|
|
14
|
+
registerFrameworkResources(server);
|
|
13
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-tools.d.ts","sourceRoot":"","sources":["../../src/tools/component-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"component-tools.d.ts","sourceRoot":"","sources":["../../src/tools/component-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2I9D"}
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
import { getComponent, getAllComponents } from "../lib/cem-parser.js";
|
|
12
12
|
import { searchComponents } from "../lib/search.js";
|
|
13
|
+
import { buildExampleSnippets, } from "../lib/framework-snippets.js";
|
|
14
|
+
import { buildAngularUsageNotes, buildReactUsageNotes, } from "../lib/framework-usage.js";
|
|
13
15
|
export function registerComponentTools(server) {
|
|
14
16
|
// find_components - Search or list all components
|
|
15
17
|
server.tool("find_components", "Search for COBWDS components by name or description. Omit query to list all components.", {
|
|
@@ -51,15 +53,19 @@ export function registerComponentTools(server) {
|
|
|
51
53
|
};
|
|
52
54
|
});
|
|
53
55
|
// get_component - Full documentation for a specific component
|
|
54
|
-
server.tool("get_component", "Get full documentation for a specific COBWDS component including properties, events, slots, and CSS custom properties", {
|
|
56
|
+
server.tool("get_component", "Get full documentation for a specific COBWDS component including properties, events, slots, and CSS custom properties. Set framework to 'react' or 'angular' to get that framework's import line, event-prop naming, and forms guidance alongside HTML/React/Angular code examples.", {
|
|
55
57
|
tagName: z
|
|
56
58
|
.string()
|
|
57
59
|
.describe("The tag name of the component (e.g., 'cob-button')"),
|
|
58
60
|
includeExamples: z
|
|
59
61
|
.boolean()
|
|
60
62
|
.default(false)
|
|
61
|
-
.describe("Include
|
|
62
|
-
|
|
63
|
+
.describe("Include code examples from component JSDoc. Set to true when you need usage patterns. Each example carries html, react, and angular snippets."),
|
|
64
|
+
framework: z
|
|
65
|
+
.enum(["html", "react", "angular"])
|
|
66
|
+
.default("html")
|
|
67
|
+
.describe("Which framework to optimize the response for. 'html' (default) returns plain custom-element usage. 'react' and 'angular' add framework-specific usage notes (import line, event-prop naming, forms binding) and, for a form-control component, transform that framework's example snippets into its idiomatic controlled/reactive-forms pattern."),
|
|
68
|
+
}, async ({ tagName, includeExamples, framework }) => {
|
|
63
69
|
const component = getComponent(tagName);
|
|
64
70
|
if (!component) {
|
|
65
71
|
return {
|
|
@@ -76,16 +82,25 @@ export function registerComponentTools(server) {
|
|
|
76
82
|
// Attributes contains the HTML API, members duplicates this plus private methods
|
|
77
83
|
const {
|
|
78
84
|
// members: _members,
|
|
79
|
-
examples, ...componentWithoutMembers } = component;
|
|
85
|
+
examples, formControl, ...componentWithoutMembers } = component;
|
|
86
|
+
const usage = {};
|
|
87
|
+
if (framework === "react") {
|
|
88
|
+
usage.react = buildReactUsageNotes(tagName, component.name, formControl);
|
|
89
|
+
}
|
|
90
|
+
else if (framework === "angular") {
|
|
91
|
+
usage.angular = buildAngularUsageNotes(tagName, component.name, formControl);
|
|
92
|
+
}
|
|
80
93
|
return {
|
|
81
94
|
content: [
|
|
82
95
|
{
|
|
83
96
|
type: "text",
|
|
84
97
|
text: JSON.stringify({
|
|
85
98
|
...componentWithoutMembers,
|
|
99
|
+
formControl,
|
|
86
100
|
examples: includeExamples && examples && examples.length > 0
|
|
87
|
-
? examples
|
|
101
|
+
? buildExampleSnippets(examples, framework, formControl)
|
|
88
102
|
: undefined,
|
|
103
|
+
usage: Object.keys(usage).length > 0 ? usage : undefined,
|
|
89
104
|
resourceUri: `cobwds://component/${tagName}`,
|
|
90
105
|
}, null, 2),
|
|
91
106
|
},
|
|
@@ -56,7 +56,7 @@ export function registerGuideTools(server) {
|
|
|
56
56
|
])
|
|
57
57
|
.describe("The guide topic to retrieve"),
|
|
58
58
|
framework: z
|
|
59
|
-
.enum(["angular", "react", "dotnet", "drupal", "vanilla"])
|
|
59
|
+
.enum(["angular", "react", "vue", "dotnet", "drupal", "vanilla"])
|
|
60
60
|
.optional()
|
|
61
61
|
.describe("When provided, returns framework-specific setup guide instead of the topic guide. Use with topic 'installation' to get framework install instructions."),
|
|
62
62
|
}, async ({ topic, framework }) => {
|
|
@@ -2,7 +2,55 @@
|
|
|
2
2
|
* Utility Tools
|
|
3
3
|
*
|
|
4
4
|
* MCP tools for COBWDS utility classes.
|
|
5
|
+
*
|
|
6
|
+
* The class lists this tool returns are RENDERED from the scale constants
|
|
7
|
+
* below. Those constants mirror the Sass sources that actually generate the
|
|
8
|
+
* stylesheet:
|
|
9
|
+
*
|
|
10
|
+
* - packages/styles/src/utilities/_config.scss ($spacing, $opacity-values,
|
|
11
|
+
* $zindex-values, $display-values,
|
|
12
|
+
* $breakpoints, $flex-columns)
|
|
13
|
+
* - packages/styles/src/utilities/_layout-grid.scss ($responsive-gap-suffixes)
|
|
14
|
+
* - packages/styles/src/core/typography.scss ($body-sizes, $ui-sizes,
|
|
15
|
+
* $ui-underline-styles, $display-sizes)
|
|
16
|
+
*
|
|
17
|
+
* Do not hand-write a class name into the markdown. Add it to a scale and let
|
|
18
|
+
* the renderer emit it, so a name can never appear here without a scale entry
|
|
19
|
+
* behind it.
|
|
20
|
+
*
|
|
21
|
+
* `npm run verify:utility-docs` compiles the stylesheet and asserts that every
|
|
22
|
+
* class this tool names exists in it. Run it after touching any scale.
|
|
5
23
|
*/
|
|
6
24
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
25
|
+
declare const UTILITY_DOCS: {
|
|
26
|
+
grid: string;
|
|
27
|
+
flex: string;
|
|
28
|
+
spacing: string;
|
|
29
|
+
display: string;
|
|
30
|
+
opacity: string;
|
|
31
|
+
zindex: string;
|
|
32
|
+
typography: string;
|
|
33
|
+
responsive: string;
|
|
34
|
+
componentSpacing: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Classes the reference deliberately names in order to say they do NOT exist.
|
|
38
|
+
*
|
|
39
|
+
* These are the names people reach for out of habit from other frameworks.
|
|
40
|
+
* Saying so explicitly is more useful than silence, but it means the docs
|
|
41
|
+
* mention class names the stylesheet does not define, which would otherwise
|
|
42
|
+
* trip the verifier.
|
|
43
|
+
*
|
|
44
|
+
* `verify-utility-docs.mjs` asserts each of these is genuinely absent, so if
|
|
45
|
+
* COBWDS ever adds one, the stale warning fails the check instead of quietly
|
|
46
|
+
* misinforming people.
|
|
47
|
+
*/
|
|
48
|
+
declare const KNOWN_ABSENT: readonly string[];
|
|
49
|
+
/**
|
|
50
|
+
* Exported so `src/scripts/verify-utility-docs.mjs` can assert that every class
|
|
51
|
+
* named in this reference exists in the compiled stylesheet — and that every
|
|
52
|
+
* class named in KNOWN_ABSENT still does not.
|
|
53
|
+
*/
|
|
54
|
+
export { UTILITY_DOCS, KNOWN_ABSENT };
|
|
7
55
|
export declare function registerUtilityTools(server: McpServer): void;
|
|
8
56
|
//# sourceMappingURL=utility-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utility-tools.d.ts","sourceRoot":"","sources":["../../src/tools/utility-tools.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"utility-tools.d.ts","sourceRoot":"","sources":["../../src/tools/utility-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiLzE,QAAA,MAAM,YAAY;;;;;;;;;;CAyOjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,YAAY,EAAE,SAAS,MAAM,EAUlC,CAAC;AAEF;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAEtC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8D5D"}
|
|
@@ -2,8 +2,150 @@
|
|
|
2
2
|
* Utility Tools
|
|
3
3
|
*
|
|
4
4
|
* MCP tools for COBWDS utility classes.
|
|
5
|
+
*
|
|
6
|
+
* The class lists this tool returns are RENDERED from the scale constants
|
|
7
|
+
* below. Those constants mirror the Sass sources that actually generate the
|
|
8
|
+
* stylesheet:
|
|
9
|
+
*
|
|
10
|
+
* - packages/styles/src/utilities/_config.scss ($spacing, $opacity-values,
|
|
11
|
+
* $zindex-values, $display-values,
|
|
12
|
+
* $breakpoints, $flex-columns)
|
|
13
|
+
* - packages/styles/src/utilities/_layout-grid.scss ($responsive-gap-suffixes)
|
|
14
|
+
* - packages/styles/src/core/typography.scss ($body-sizes, $ui-sizes,
|
|
15
|
+
* $ui-underline-styles, $display-sizes)
|
|
16
|
+
*
|
|
17
|
+
* Do not hand-write a class name into the markdown. Add it to a scale and let
|
|
18
|
+
* the renderer emit it, so a name can never appear here without a scale entry
|
|
19
|
+
* behind it.
|
|
20
|
+
*
|
|
21
|
+
* `npm run verify:utility-docs` compiles the stylesheet and asserts that every
|
|
22
|
+
* class this tool names exists in it. Run it after touching any scale.
|
|
5
23
|
*/
|
|
6
24
|
import { z } from "zod";
|
|
25
|
+
/**
|
|
26
|
+
* `$spacing` in _config.scss. The utilities emit literal pixel values, not
|
|
27
|
+
* `var(--cob-space-*)` references, so the rendered docs quote pixels.
|
|
28
|
+
*
|
|
29
|
+
* There is deliberately no `0` key: `cob-margin-0` and `cob-padding-0` are
|
|
30
|
+
* not generated.
|
|
31
|
+
*/
|
|
32
|
+
const SPACING = [
|
|
33
|
+
["1px", "1px"],
|
|
34
|
+
["2px", "2px"],
|
|
35
|
+
["50", "4px", "0.25rem"],
|
|
36
|
+
["100", "8px", "0.5rem"],
|
|
37
|
+
["150", "12px", "0.75rem"],
|
|
38
|
+
["200", "16px", "1rem"],
|
|
39
|
+
["250", "20px", "1.25rem"],
|
|
40
|
+
["300", "24px", "1.5rem"],
|
|
41
|
+
["400", "32px", "2rem"],
|
|
42
|
+
["500", "40px", "2.5rem"],
|
|
43
|
+
["600", "48px", "3rem"],
|
|
44
|
+
["700", "56px", "3.5rem"],
|
|
45
|
+
["800", "64px", "4rem"],
|
|
46
|
+
["1200", "96px", "6rem"],
|
|
47
|
+
];
|
|
48
|
+
/** `$responsive-gap-suffixes` in _layout-grid.scss. */
|
|
49
|
+
const RESPONSIVE_GAP_KEYS = [
|
|
50
|
+
"400",
|
|
51
|
+
"500",
|
|
52
|
+
"600",
|
|
53
|
+
"700",
|
|
54
|
+
"800",
|
|
55
|
+
"1200",
|
|
56
|
+
];
|
|
57
|
+
/** `$opacity-values` in _config.scss. */
|
|
58
|
+
const OPACITY = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
|
|
59
|
+
/** `$zindex-values` in _config.scss. */
|
|
60
|
+
const ZINDEX = [
|
|
61
|
+
["0", "0"],
|
|
62
|
+
["100", "100"],
|
|
63
|
+
["200", "200"],
|
|
64
|
+
["300", "300"],
|
|
65
|
+
["400", "400"],
|
|
66
|
+
["500", "500"],
|
|
67
|
+
["auto", "auto"],
|
|
68
|
+
["bottom", "-100"],
|
|
69
|
+
["top", "99999"],
|
|
70
|
+
];
|
|
71
|
+
/** `$display-values` in _config.scss. */
|
|
72
|
+
const DISPLAY = [
|
|
73
|
+
"none",
|
|
74
|
+
"block",
|
|
75
|
+
"inline",
|
|
76
|
+
"inline-block",
|
|
77
|
+
"flex",
|
|
78
|
+
"inline-flex",
|
|
79
|
+
"table",
|
|
80
|
+
"table-cell",
|
|
81
|
+
"table-row",
|
|
82
|
+
];
|
|
83
|
+
/** `$breakpoints` in _config.scss. */
|
|
84
|
+
const BREAKPOINTS = [
|
|
85
|
+
["mobile-lg", "30em", "480px"],
|
|
86
|
+
["tablet", "40em", "640px"],
|
|
87
|
+
["desktop", "64em", "1024px"],
|
|
88
|
+
["widescreen", "87.5em", "1400px"],
|
|
89
|
+
];
|
|
90
|
+
/** Typography scales in core/typography.scss. */
|
|
91
|
+
const HEADING_LEVELS = [1, 2, 3, 4, 5, 6];
|
|
92
|
+
const BODY_SIZES = ["xs", "sm", "md"];
|
|
93
|
+
const UI_SIZES = ["xs", "sm", "md", "lg", "xl"];
|
|
94
|
+
const DISPLAY_SIZES = ["sm", "md", "lg", "xl"];
|
|
95
|
+
/** `$ui-underline-styles` — only these size/weight pairs are generated. */
|
|
96
|
+
const UI_UNDERLINE = [
|
|
97
|
+
["sm", "semibold"],
|
|
98
|
+
["md", "semibold"],
|
|
99
|
+
["md", "regular"],
|
|
100
|
+
["lg", "semibold"],
|
|
101
|
+
];
|
|
102
|
+
const FLEX_ALIGN = [
|
|
103
|
+
"start",
|
|
104
|
+
"center",
|
|
105
|
+
"end",
|
|
106
|
+
"baseline",
|
|
107
|
+
"stretch",
|
|
108
|
+
];
|
|
109
|
+
const FLEX_JUSTIFY = [
|
|
110
|
+
"start",
|
|
111
|
+
"center",
|
|
112
|
+
"end",
|
|
113
|
+
"space-between",
|
|
114
|
+
"space-around",
|
|
115
|
+
"space-evenly",
|
|
116
|
+
];
|
|
117
|
+
/* ------------------------------------------------------------------ *
|
|
118
|
+
* Renderers
|
|
119
|
+
* ------------------------------------------------------------------ */
|
|
120
|
+
const spacingKeys = SPACING.map(([key]) => key);
|
|
121
|
+
const bullets = (lines) => lines.join("\n");
|
|
122
|
+
const inlineList = (items) => items.map((i) => `\`${i}\``).join(", ");
|
|
123
|
+
const spacingValueRows = bullets(SPACING.map(([key, px, rem]) => `- \`${key}\` - ${px}${rem ? ` (${rem})` : ""}`));
|
|
124
|
+
const gapValueRows = bullets(SPACING.map(([key, px, rem]) => {
|
|
125
|
+
const size = `${px}${rem ? ` (${rem})` : ""}`;
|
|
126
|
+
// Gaps in the responsive set are capped at 2rem below 64em. For 400 the
|
|
127
|
+
// cap equals the full value, so only note it where it actually differs.
|
|
128
|
+
const capped = RESPONSIVE_GAP_KEYS.includes(key) && Number.parseInt(px, 10) > 32;
|
|
129
|
+
return capped
|
|
130
|
+
? `- \`cob-grid-gap-${key}\` - ${size} at 64em and up, capped at 32px (2rem) below that`
|
|
131
|
+
: `- \`cob-grid-gap-${key}\` - ${size}`;
|
|
132
|
+
}));
|
|
133
|
+
const opacityRows = bullets(OPACITY.map((v) => {
|
|
134
|
+
const label = v === 0
|
|
135
|
+
? "Fully transparent"
|
|
136
|
+
: v === 100
|
|
137
|
+
? "Fully opaque"
|
|
138
|
+
: `${v}% opaque`;
|
|
139
|
+
return `- \`cob-opacity-${v}\` - opacity: ${v / 100} (${label})`;
|
|
140
|
+
}));
|
|
141
|
+
const zindexRows = bullets(ZINDEX.map(([name, value]) => `- \`cob-z-${name}\` - z-index: ${value}`));
|
|
142
|
+
const displayRows = bullets(DISPLAY.map((v) => `- \`cob-display-${v}\` - display: ${v}`));
|
|
143
|
+
const breakpointRows = bullets(BREAKPOINTS.map(([name, em, px]) => `- \`cob-${name}:\` - ${em} (${px}) and up`));
|
|
144
|
+
const headingRows = bullets(HEADING_LEVELS.map((n) => `- \`cob-font-h${n}\` - Heading level ${n} type style`));
|
|
145
|
+
const underlineRows = bullets(UI_UNDERLINE.flatMap(([size, weight]) => [
|
|
146
|
+
`- \`cob-font-ui-${size}-${weight}-underline\` - UI ${size} ${weight}, 7% underline`,
|
|
147
|
+
`- \`cob-font-ui-${size}-${weight}-underline-strong\` - UI ${size} ${weight}, 14% underline`,
|
|
148
|
+
]));
|
|
7
149
|
const UTILITY_DOCS = {
|
|
8
150
|
grid: `## Grid System
|
|
9
151
|
|
|
@@ -26,20 +168,11 @@ COBWDS provides a 12-column responsive grid system.
|
|
|
26
168
|
- \`cob-grid-col-fill\` - Column fills remaining space
|
|
27
169
|
|
|
28
170
|
### Gap Classes
|
|
29
|
-
- \`cob-grid-gap-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- \`cob-grid-gap-200\` - 16px gap (1rem)
|
|
35
|
-
- \`cob-grid-gap-250\` - 20px gap (1.25rem)
|
|
36
|
-
- \`cob-grid-gap-300\` - 24px gap (1.5rem)
|
|
37
|
-
- \`cob-grid-gap-400\` - 32px gap (2rem)
|
|
38
|
-
- \`cob-grid-gap-500\` - 40px gap (2.5rem)
|
|
39
|
-
- \`cob-grid-gap-600\` - 48px gap (3rem)
|
|
40
|
-
- \`cob-grid-gap-700\` - 56px gap (3.5rem)
|
|
41
|
-
- \`cob-grid-gap-800\` - 64px gap (4rem)
|
|
42
|
-
- \`cob-grid-gap-1200\` - 96px gap (6rem)
|
|
171
|
+
Gap classes apply to \`cob-grid-row\`. Use \`cob-grid-gap-x-*\` or
|
|
172
|
+
\`cob-grid-gap-y-*\` for a single axis. There is no \`cob-grid-gap-0\`; omit
|
|
173
|
+
the gap class instead.
|
|
174
|
+
|
|
175
|
+
${gapValueRows}
|
|
43
176
|
|
|
44
177
|
### Offset Classes
|
|
45
178
|
- \`cob-grid-offset-[1-12]\` - Offset column by 1-12 columns
|
|
@@ -61,6 +194,7 @@ COBWDS provides a 12-column responsive grid system.
|
|
|
61
194
|
|
|
62
195
|
### Display
|
|
63
196
|
- \`cob-display-flex\` - Sets display: flex
|
|
197
|
+
- \`cob-display-inline-flex\` - Sets display: inline-flex
|
|
64
198
|
|
|
65
199
|
### Direction
|
|
66
200
|
- \`cob-flex-row\` - Row direction (default)
|
|
@@ -71,21 +205,26 @@ COBWDS provides a 12-column responsive grid system.
|
|
|
71
205
|
- \`cob-flex-no-wrap\` - Prevent wrapping
|
|
72
206
|
|
|
73
207
|
### Alignment (Cross Axis)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
208
|
+
${bullets(FLEX_ALIGN.map((v) => `- \`cob-flex-align-${v}\` - align-items: ${v}`))}
|
|
209
|
+
|
|
210
|
+
### Self Alignment
|
|
211
|
+
${bullets(FLEX_ALIGN.map((v) => `- \`cob-flex-align-self-${v}\` - align-self: ${v}`))}
|
|
78
212
|
|
|
79
213
|
### Justification (Main Axis)
|
|
80
|
-
|
|
81
|
-
- \`cob-flex-justify-center\` - Justify to center
|
|
82
|
-
- \`cob-flex-justify-end\` - Justify to end
|
|
214
|
+
${bullets(FLEX_JUSTIFY.map((v) => `- \`cob-flex-justify-${v}\` - justify-content: ${v}`))}
|
|
83
215
|
|
|
84
216
|
### Flex Sizing
|
|
85
217
|
- \`cob-flex-[1-12]\` - Flex grow/shrink values
|
|
86
218
|
- \`cob-flex-auto\` - flex: auto (grow and shrink)
|
|
87
219
|
- \`cob-flex-fill\` - Fill available space
|
|
88
220
|
|
|
221
|
+
### Gaps
|
|
222
|
+
Available on the spacing scale: ${inlineList(spacingKeys)}
|
|
223
|
+
|
|
224
|
+
- \`cob-flex-gap-{value}\` - gap on both axes
|
|
225
|
+
- \`cob-flex-row-gap-{value}\` - row-gap only
|
|
226
|
+
- \`cob-flex-column-gap-{value}\` - column-gap only
|
|
227
|
+
|
|
89
228
|
### Example: Button Group
|
|
90
229
|
\`\`\`html
|
|
91
230
|
<div class="cob-display-flex cob-flex-justify-end cob-flex-gap-200">
|
|
@@ -111,21 +250,11 @@ Pattern: \`cob-{property}-{direction}-{value}\`
|
|
|
111
250
|
- (none) - All sides
|
|
112
251
|
|
|
113
252
|
### Values
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- \`150\` - var(--cob-space-150) = 0.375rem (6px)
|
|
120
|
-
- \`200\` - var(--cob-space-200) = 0.5rem (8px)
|
|
121
|
-
- \`250\` - var(--cob-space-250) = 0.625rem (10px)
|
|
122
|
-
- \`300\` - var(--cob-space-300) = 0.75rem (12px)
|
|
123
|
-
- \`400\` - var(--cob-space-400) = 1rem (16px)
|
|
124
|
-
- \`500\` - var(--cob-space-500) = 1.25rem (20px)
|
|
125
|
-
- \`600\` - var(--cob-space-600) = 1.5rem (24px)
|
|
126
|
-
- \`700\` - var(--cob-space-700) = 2rem (32px)
|
|
127
|
-
- \`800\` - var(--cob-space-800) = 2.5rem (40px)
|
|
128
|
-
- \`1200\` - var(--cob-space-1200) = 4rem (64px)
|
|
253
|
+
The utilities emit literal pixel values. There is no zero and no \`auto\`
|
|
254
|
+
value — \`cob-margin-0\` and \`cob-padding-0\` are not generated. Omit the
|
|
255
|
+
class instead.
|
|
256
|
+
|
|
257
|
+
${spacingValueRows}
|
|
129
258
|
|
|
130
259
|
### Examples
|
|
131
260
|
\`\`\`html
|
|
@@ -140,11 +269,7 @@ Pattern: \`cob-{property}-{direction}-{value}\`
|
|
|
140
269
|
\`\`\``,
|
|
141
270
|
display: `## Display Utilities
|
|
142
271
|
|
|
143
|
-
|
|
144
|
-
- \`cob-display-block\` - Block display
|
|
145
|
-
- \`cob-display-inline\` - Inline display
|
|
146
|
-
- \`cob-display-inline-block\` - Inline-block display
|
|
147
|
-
- \`cob-display-flex\` - Flex display
|
|
272
|
+
${displayRows}
|
|
148
273
|
|
|
149
274
|
### Example: Hide on Mobile
|
|
150
275
|
\`\`\`html
|
|
@@ -154,46 +279,57 @@ Pattern: \`cob-{property}-{direction}-{value}\`
|
|
|
154
279
|
\`\`\``,
|
|
155
280
|
opacity: `## Opacity Utilities
|
|
156
281
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- \`cob-opacity-75\` - 75% opacity
|
|
161
|
-
- \`cob-opacity-100\` - Fully opaque`,
|
|
282
|
+
The scale steps by 10 — there is no \`cob-opacity-25\` or \`cob-opacity-75\`.
|
|
283
|
+
|
|
284
|
+
${opacityRows}`,
|
|
162
285
|
zindex: `## Z-Index Utilities
|
|
163
286
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
- \`cob-z-40\` - z-index: 40
|
|
169
|
-
- \`cob-z-50\` - z-index: 50
|
|
170
|
-
- \`cob-z-auto\` - z-index: auto`,
|
|
287
|
+
The scale steps by 100, not by 10. \`cob-z-10\` through \`cob-z-50\` do not
|
|
288
|
+
exist — the comparable values are \`cob-z-100\` through \`cob-z-500\`.
|
|
289
|
+
|
|
290
|
+
${zindexRows}`,
|
|
171
291
|
typography: `## Typography Utilities
|
|
172
292
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
293
|
+
COBWDS ships a role-based type scale, not atomic text modifiers. Each class
|
|
294
|
+
sets font-family, size, and line-height together, matching the text styles in
|
|
295
|
+
the COBWDS Foundations Figma file.
|
|
296
|
+
|
|
297
|
+
There are NO text-alignment, text-transform, or font-weight utilities
|
|
298
|
+
(no \`cob-text-center\`, no \`cob-font-bold\`). Use CSS for those.
|
|
299
|
+
|
|
300
|
+
### Headings
|
|
301
|
+
${headingRows}
|
|
302
|
+
|
|
303
|
+
### Body
|
|
304
|
+
${bullets(BODY_SIZES.map((s) => `- \`cob-font-body-${s}\` - Body text, ${s}`))}
|
|
305
|
+
|
|
306
|
+
### UI
|
|
307
|
+
${bullets(UI_SIZES.map((s) => `- \`cob-font-ui-${s}\` - UI text, ${s}`))}
|
|
308
|
+
|
|
309
|
+
### UI Underline
|
|
310
|
+
${underlineRows}
|
|
311
|
+
|
|
312
|
+
### Display
|
|
313
|
+
${bullets(DISPLAY_SIZES.map((s) => `- \`cob-font-display-${s}\` - Display text, ${s}`))}
|
|
314
|
+
|
|
315
|
+
### Agency
|
|
316
|
+
- \`cob-font-agency\` - Agency / application title
|
|
317
|
+
|
|
318
|
+
### Font family hooks
|
|
319
|
+
These are attribute selectors, not standalone classes. They set only
|
|
320
|
+
font-family on any element whose class list contains the substring, so pair
|
|
321
|
+
them with a size class:
|
|
322
|
+
|
|
323
|
+
- \`[class*="cob-font-mono-"]\` - monospace family
|
|
324
|
+
- \`[class*="cob-font-sans-"]\` - sans-serif family
|
|
325
|
+
- \`[class*="cob-font-serif-"]\` - serif family`,
|
|
188
326
|
responsive: `## Responsive Breakpoints
|
|
189
327
|
|
|
190
328
|
COBWDS utility classes support responsive prefixes.
|
|
191
329
|
|
|
192
330
|
### Breakpoints
|
|
193
331
|
- (no prefix) - All screen sizes (mobile-first)
|
|
194
|
-
|
|
195
|
-
- \`cob-tablet:\` - 40em (640px) and up
|
|
196
|
-
- \`cob-desktop:\` - 64em (1024px) and up
|
|
332
|
+
${breakpointRows}
|
|
197
333
|
|
|
198
334
|
### Pattern
|
|
199
335
|
\`cob-{breakpoint}:cob-{class}\`
|
|
@@ -236,6 +372,35 @@ When adding spacing around COBWDS components, use utility classes rather than wr
|
|
|
236
372
|
<cob-button label="Submit"></cob-button>
|
|
237
373
|
\`\`\``,
|
|
238
374
|
};
|
|
375
|
+
/**
|
|
376
|
+
* Classes the reference deliberately names in order to say they do NOT exist.
|
|
377
|
+
*
|
|
378
|
+
* These are the names people reach for out of habit from other frameworks.
|
|
379
|
+
* Saying so explicitly is more useful than silence, but it means the docs
|
|
380
|
+
* mention class names the stylesheet does not define, which would otherwise
|
|
381
|
+
* trip the verifier.
|
|
382
|
+
*
|
|
383
|
+
* `verify-utility-docs.mjs` asserts each of these is genuinely absent, so if
|
|
384
|
+
* COBWDS ever adds one, the stale warning fails the check instead of quietly
|
|
385
|
+
* misinforming people.
|
|
386
|
+
*/
|
|
387
|
+
const KNOWN_ABSENT = [
|
|
388
|
+
"cob-text-center",
|
|
389
|
+
"cob-font-bold",
|
|
390
|
+
"cob-z-10",
|
|
391
|
+
"cob-z-50",
|
|
392
|
+
"cob-opacity-25",
|
|
393
|
+
"cob-opacity-75",
|
|
394
|
+
"cob-margin-0",
|
|
395
|
+
"cob-padding-0",
|
|
396
|
+
"cob-grid-gap-0",
|
|
397
|
+
];
|
|
398
|
+
/**
|
|
399
|
+
* Exported so `src/scripts/verify-utility-docs.mjs` can assert that every class
|
|
400
|
+
* named in this reference exists in the compiled stylesheet — and that every
|
|
401
|
+
* class named in KNOWN_ABSENT still does not.
|
|
402
|
+
*/
|
|
403
|
+
export { UTILITY_DOCS, KNOWN_ABSENT };
|
|
239
404
|
export function registerUtilityTools(server) {
|
|
240
405
|
// get_utility_classes - Comprehensive utility class reference
|
|
241
406
|
server.tool("get_utility_classes", "Get COBWDS utility class reference for layout, spacing, and styling", {
|