@trishchuk/coolors-mcp 1.0.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/.claude/settings.local.json +39 -0
- package/.env +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +73 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +71 -0
- package/.github/pull_request_template.md +97 -0
- package/.github/workflows/ci.yml +127 -0
- package/.github/workflows/deploy-docs.yml +56 -0
- package/.github/workflows/release.yml +99 -0
- package/.mcp.json +12 -0
- package/.prettierignore +1 -0
- package/CLAUDE.md +201 -0
- package/DOCUMENTATION.md +274 -0
- package/GEMINI.md +54 -0
- package/LICENSE +21 -0
- package/README.md +401 -0
- package/demo/content_based_color.png +0 -0
- package/demo/music-player.html +621 -0
- package/demo/podcast-player.html +903 -0
- package/dist/bin/coolors-mcp.d.ts +1 -0
- package/dist/bin/coolors-mcp.js +154 -0
- package/dist/bin/coolors-mcp.js.map +1 -0
- package/dist/bin/server.d.ts +1 -0
- package/dist/bin/server.js +3292 -0
- package/dist/bin/server.js.map +1 -0
- package/dist/chunk-IQ7NN26V.js +114 -0
- package/dist/chunk-IQ7NN26V.js.map +1 -0
- package/dist/chunk-P3ARRKLS.js +1214 -0
- package/dist/chunk-P3ARRKLS.js.map +1 -0
- package/dist/color/index.d.ts +716 -0
- package/dist/color/index.js +153 -0
- package/dist/color/index.js.map +1 -0
- package/dist/coolors-mcp.d.ts +136 -0
- package/dist/coolors-mcp.js +7 -0
- package/dist/coolors-mcp.js.map +1 -0
- package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js +93 -0
- package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js.map +7 -0
- package/docs/.vitepress/cache/deps/_metadata.json +127 -0
- package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -0
- package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +7 -0
- package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js +12683 -0
- package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js.map +7 -0
- package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js +9719 -0
- package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js.map +7 -0
- package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js +4710 -0
- package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +7 -0
- package/docs/.vitepress/cache/deps/cytoscape.js +30278 -0
- package/docs/.vitepress/cache/deps/cytoscape.js.map +7 -0
- package/docs/.vitepress/cache/deps/dayjs.js +285 -0
- package/docs/.vitepress/cache/deps/dayjs.js.map +7 -0
- package/docs/.vitepress/cache/deps/debug.js +468 -0
- package/docs/.vitepress/cache/deps/debug.js.map +7 -0
- package/docs/.vitepress/cache/deps/package.json +3 -0
- package/docs/.vitepress/cache/deps/prismjs.js +1466 -0
- package/docs/.vitepress/cache/deps/prismjs.js.map +7 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js +228 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js.map +7 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js +142 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js.map +7 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js +27 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js.map +7 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js +65 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js.map +7 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js +53 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js.map +7 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js +73 -0
- package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4507 -0
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +584 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1146 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1667 -0
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js +1814 -0
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
- package/docs/.vitepress/cache/deps/vue.js +344 -0
- package/docs/.vitepress/cache/deps/vue.js.map +7 -0
- package/docs/.vitepress/components/ClientGrid.vue +125 -0
- package/docs/.vitepress/components/CodeBlock.vue +231 -0
- package/docs/.vitepress/components/ConfigModal.vue +477 -0
- package/docs/.vitepress/components/DiagramModal.vue +528 -0
- package/docs/.vitepress/components/TroubleshootingModal.vue +472 -0
- package/docs/.vitepress/config.js +162 -0
- package/docs/.vitepress/theme/FundingLayout.vue +251 -0
- package/docs/.vitepress/theme/Layout.vue +134 -0
- package/docs/.vitepress/theme/components/AdBanner.vue +317 -0
- package/docs/.vitepress/theme/components/AdPlaceholder.vue +78 -0
- package/docs/.vitepress/theme/components/FundingEffects.vue +322 -0
- package/docs/.vitepress/theme/components/FundingHero.vue +345 -0
- package/docs/.vitepress/theme/components/SupportSection.vue +511 -0
- package/docs/.vitepress/theme/custom-app.css +339 -0
- package/docs/.vitepress/theme/custom.css +699 -0
- package/docs/.vitepress/theme/index.js +25 -0
- package/docs/README.md +198 -0
- package/docs/concepts/accessibility.md +473 -0
- package/docs/concepts/color-spaces.md +222 -0
- package/docs/concepts/distance-metrics.md +384 -0
- package/docs/concepts/hct.md +261 -0
- package/docs/concepts/image-analysis.md +396 -0
- package/docs/concepts/material-design.md +306 -0
- package/docs/concepts/theme-matching.md +399 -0
- package/docs/examples/basic-colors.md +490 -0
- package/docs/examples/creating-themes.md +898 -0
- package/docs/examples/css-refactoring.md +824 -0
- package/docs/examples/image-extraction.md +882 -0
- package/docs/getting-started.md +366 -0
- package/docs/index.md +190 -0
- package/docs/installation.md +157 -0
- package/docs/tools/README.md +234 -0
- package/docs/tools/accessibility.md +614 -0
- package/docs/tools/color-operations.md +374 -0
- package/docs/tools/image-extraction.md +624 -0
- package/docs/tools/material-design.md +347 -0
- package/docs/tools/theme-matching.md +552 -0
- package/eslint.config.ts +14 -0
- package/examples/theme-matching.md +113 -0
- package/jsr.json +7 -0
- package/mcp-config.json +8 -0
- package/note.md +35 -0
- package/package.json +122 -0
- package/research_results.md +53 -0
- package/src/bin/coolors-mcp.ts +194 -0
- package/src/bin/server.ts +61 -0
- package/src/color/__tests__/conversions-argb.test.ts +198 -0
- package/src/color/__tests__/extract-colors.test.ts +360 -0
- package/src/color/__tests__/image-utils.test.ts +242 -0
- package/src/color/__tests__/reference-colors.test.ts +278 -0
- package/src/color/__tests__/round-trip.test.ts +197 -0
- package/src/color/conversions.test.ts +402 -0
- package/src/color/conversions.ts +393 -0
- package/src/color/dislike/__tests__/dislike-analyzer.test.ts +248 -0
- package/src/color/dislike/dislike-analyzer.ts +114 -0
- package/src/color/extract-colors.ts +228 -0
- package/src/color/hct/__tests__/hct-class.test.ts +232 -0
- package/src/color/hct/harmonization.ts +204 -0
- package/src/color/hct/hct-class.ts +109 -0
- package/src/color/hct/hct-solver.ts +168 -0
- package/src/color/hct/index.ts +39 -0
- package/src/color/hct/tonal-palette.ts +211 -0
- package/src/color/hct/types.ts +88 -0
- package/src/color/image-utils.ts +79 -0
- package/src/color/index.ts +87 -0
- package/src/color/material-theme.ts +157 -0
- package/src/color/metrics.test.ts +276 -0
- package/src/color/metrics.ts +281 -0
- package/src/color/quantize/__tests__/quantizer_celebi.test.ts +195 -0
- package/src/color/quantize/lab_point_provider.ts +55 -0
- package/src/color/quantize/point_provider.ts +27 -0
- package/src/color/quantize/quantizer_celebi.ts +51 -0
- package/src/color/quantize/quantizer_celebi_test.ts +71 -0
- package/src/color/quantize/quantizer_map.ts +47 -0
- package/src/color/quantize/quantizer_wsmeans.ts +232 -0
- package/src/color/quantize/quantizer_wu.ts +472 -0
- package/src/color/score/__tests__/score.test.ts +224 -0
- package/src/color/score/score.ts +175 -0
- package/src/color/types.ts +151 -0
- package/src/color/utils/color_utils.ts +292 -0
- package/src/color/utils/math_utils.ts +145 -0
- package/src/color/utils.test.ts +403 -0
- package/src/color/utils.ts +315 -0
- package/src/constants.ts +5 -0
- package/src/coolors-mcp.ts +37 -0
- package/src/examples/addition.ts +333 -0
- package/src/examples/color-demo.ts +125 -0
- package/src/examples/custom-logger.ts +201 -0
- package/src/examples/oauth-server.ts +113 -0
- package/src/examples/session-context.ts +269 -0
- package/src/session.ts +116 -0
- package/src/theme/__tests__/matcher.test.ts +180 -0
- package/src/theme/__tests__/parser.test.ts +148 -0
- package/src/theme/__tests__/refactor.test.ts +224 -0
- package/src/theme/index.ts +34 -0
- package/src/theme/matcher.ts +395 -0
- package/src/theme/parser.ts +392 -0
- package/src/theme/refactor.ts +360 -0
- package/src/theme/types.ts +152 -0
- package/src/tools/__tests__/gradient-generator.test.ts +206 -0
- package/src/tools/__tests__/palette-with-locks.test.ts +109 -0
- package/src/tools/color-conversion.tool.ts +54 -0
- package/src/tools/color-distance.tool.ts +41 -0
- package/src/tools/colors.ts +31 -0
- package/src/tools/contrast-checker.tool.ts +37 -0
- package/src/tools/dislike-analyzer.tool.ts +247 -0
- package/src/tools/gradient-generator.tool.ts +250 -0
- package/src/tools/image-extraction.tools.ts +289 -0
- package/src/tools/index.ts +39 -0
- package/src/tools/material-theme.tools.ts +250 -0
- package/src/tools/palette-generator.tool.ts +135 -0
- package/src/tools/palette-with-locks.tool.ts +221 -0
- package/src/tools/registry.ts +142 -0
- package/src/tools/simple-tools.ts +37 -0
- package/src/tools/theme-matching.tools.ts +334 -0
- package/src/types.ts +182 -0
- package/src/utils.ts +22 -0
- package/tsconfig.json +8 -0
- package/vitest.config.js +15 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
# Theme Matching Tools
|
|
2
|
+
|
|
3
|
+
Tools for matching colors to CSS theme variables and automated refactoring.
|
|
4
|
+
|
|
5
|
+
## match_theme_color
|
|
6
|
+
|
|
7
|
+
Find the closest matching theme variable for a given color.
|
|
8
|
+
|
|
9
|
+
### Parameters
|
|
10
|
+
|
|
11
|
+
| Parameter | Type | Required | Description |
|
|
12
|
+
|-----------|------|----------|-------------|
|
|
13
|
+
| `color` | string | ✅ | Color to match (hex, rgb, hsl) |
|
|
14
|
+
| `themeCSS` | string | ✅ | CSS containing theme variables |
|
|
15
|
+
| `context` | string | ❌ | Usage context: text, background, border, shadow, accent, decorative |
|
|
16
|
+
| `minConfidence` | number | ❌ | Minimum confidence threshold (0-100, default: 70) |
|
|
17
|
+
|
|
18
|
+
### Returns
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
{
|
|
22
|
+
match: string; // CSS variable name
|
|
23
|
+
confidence: number; // Confidence score (0-100)
|
|
24
|
+
originalColor: string; // Input color
|
|
25
|
+
themeColor: string; // Matched theme color
|
|
26
|
+
distance: number; // Perceptual distance
|
|
27
|
+
semantic: {
|
|
28
|
+
role: string; // Detected semantic role
|
|
29
|
+
compatible: boolean; // Context compatibility
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Examples
|
|
35
|
+
|
|
36
|
+
#### Basic Matching
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
// Find closest theme variable
|
|
40
|
+
{
|
|
41
|
+
"name": "match_theme_color",
|
|
42
|
+
"arguments": {
|
|
43
|
+
"color": "#6366f1",
|
|
44
|
+
"themeCSS": ":root { --color-primary-500: #6366f1; --color-primary-600: #4f46e5; }"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Response
|
|
49
|
+
{
|
|
50
|
+
"match": "--color-primary-500",
|
|
51
|
+
"confidence": 100,
|
|
52
|
+
"originalColor": "#6366f1",
|
|
53
|
+
"themeColor": "#6366f1",
|
|
54
|
+
"distance": 0,
|
|
55
|
+
"semantic": {
|
|
56
|
+
"role": "primary",
|
|
57
|
+
"compatible": true
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Context-Aware Matching
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
// Match for specific usage
|
|
66
|
+
{
|
|
67
|
+
"name": "match_theme_color",
|
|
68
|
+
"arguments": {
|
|
69
|
+
"color": "#e5e7eb",
|
|
70
|
+
"themeCSS": ":root { --color-border: #e5e7eb; --color-gray-200: #e5e7eb; }",
|
|
71
|
+
"context": "border"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Prefers semantic match
|
|
76
|
+
{
|
|
77
|
+
"match": "--color-border",
|
|
78
|
+
"confidence": 100,
|
|
79
|
+
"semantic": {
|
|
80
|
+
"role": "border",
|
|
81
|
+
"compatible": true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### With Confidence Threshold
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
// Only return high-confidence matches
|
|
90
|
+
{
|
|
91
|
+
"name": "match_theme_color",
|
|
92
|
+
"arguments": {
|
|
93
|
+
"color": "#6365f0",
|
|
94
|
+
"themeCSS": ":root { --color-primary: #6366f1; }",
|
|
95
|
+
"minConfidence": 95
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Close but not exact
|
|
100
|
+
{
|
|
101
|
+
"match": "--color-primary",
|
|
102
|
+
"confidence": 98.5,
|
|
103
|
+
"distance": 1.2
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Use Cases
|
|
108
|
+
|
|
109
|
+
- Finding existing theme variables for colors
|
|
110
|
+
- Identifying duplicate color definitions
|
|
111
|
+
- Migrating hardcoded colors to variables
|
|
112
|
+
- Validating color consistency
|
|
113
|
+
|
|
114
|
+
## refactor_css_with_theme
|
|
115
|
+
|
|
116
|
+
Automatically replace hardcoded colors with theme variables in CSS.
|
|
117
|
+
|
|
118
|
+
### Parameters
|
|
119
|
+
|
|
120
|
+
| Parameter | Type | Required | Description |
|
|
121
|
+
|-----------|------|----------|-------------|
|
|
122
|
+
| `css` | string | ✅ | CSS content to refactor |
|
|
123
|
+
| `themeCSS` | string | ✅ | CSS containing theme variables |
|
|
124
|
+
| `minConfidence` | number | ❌ | Minimum confidence for replacements (default: 70) |
|
|
125
|
+
| `preserveOriginal` | boolean | ❌ | Keep original values as comments (default: true) |
|
|
126
|
+
| `generateReport` | boolean | ❌ | Generate detailed refactoring report (default: false) |
|
|
127
|
+
|
|
128
|
+
### Returns
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
{
|
|
132
|
+
refactoredCSS: string; // Updated CSS
|
|
133
|
+
changes: Array<{
|
|
134
|
+
original: string; // Original color
|
|
135
|
+
replacement: string; // Theme variable
|
|
136
|
+
confidence: number; // Match confidence
|
|
137
|
+
line: number; // Line number
|
|
138
|
+
}>;
|
|
139
|
+
report?: {
|
|
140
|
+
totalColors: number;
|
|
141
|
+
replaced: number;
|
|
142
|
+
skipped: number;
|
|
143
|
+
averageConfidence: number;
|
|
144
|
+
unmatchedColors: string[];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Examples
|
|
150
|
+
|
|
151
|
+
#### Basic Refactoring
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
{
|
|
155
|
+
"name": "refactor_css_with_theme",
|
|
156
|
+
"arguments": {
|
|
157
|
+
"css": ".button { background: #6366f1; color: #ffffff; }",
|
|
158
|
+
"themeCSS": ":root { --primary: #6366f1; --white: #ffffff; }"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Result
|
|
163
|
+
{
|
|
164
|
+
"refactoredCSS": ".button {\n background: var(--primary); /* was: #6366f1 */\n color: var(--white); /* was: #ffffff */\n}",
|
|
165
|
+
"changes": [
|
|
166
|
+
{ "original": "#6366f1", "replacement": "--primary", "confidence": 100 },
|
|
167
|
+
{ "original": "#ffffff", "replacement": "--white", "confidence": 100 }
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Complex CSS Refactoring
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
{
|
|
176
|
+
"name": "refactor_css_with_theme",
|
|
177
|
+
"arguments": {
|
|
178
|
+
"css": `
|
|
179
|
+
.card {
|
|
180
|
+
background: #ffffff;
|
|
181
|
+
border: 1px solid #e5e7eb;
|
|
182
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
183
|
+
}
|
|
184
|
+
.card-title {
|
|
185
|
+
color: #1f2937;
|
|
186
|
+
}
|
|
187
|
+
`,
|
|
188
|
+
"themeCSS": `
|
|
189
|
+
:root {
|
|
190
|
+
--color-white: #ffffff;
|
|
191
|
+
--color-border: #e5e7eb;
|
|
192
|
+
--color-text: #1f2937;
|
|
193
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
194
|
+
}
|
|
195
|
+
`,
|
|
196
|
+
"preserveOriginal": true
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### With Report Generation
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
{
|
|
205
|
+
"name": "refactor_css_with_theme",
|
|
206
|
+
"arguments": {
|
|
207
|
+
"css": "/* your CSS */",
|
|
208
|
+
"themeCSS": "/* theme */",
|
|
209
|
+
"generateReport": true,
|
|
210
|
+
"minConfidence": 80
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Includes detailed report
|
|
215
|
+
{
|
|
216
|
+
"report": {
|
|
217
|
+
"totalColors": 15,
|
|
218
|
+
"replaced": 12,
|
|
219
|
+
"skipped": 3,
|
|
220
|
+
"averageConfidence": 92.5,
|
|
221
|
+
"unmatchedColors": ["#123456", "#789abc", "#def012"]
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Use Cases
|
|
227
|
+
|
|
228
|
+
- Migrating legacy CSS to use variables
|
|
229
|
+
- Enforcing consistent color usage
|
|
230
|
+
- Identifying hardcoded colors
|
|
231
|
+
- Modernizing stylesheets
|
|
232
|
+
|
|
233
|
+
## match_theme_colors_batch
|
|
234
|
+
|
|
235
|
+
Match multiple colors to theme variables in a single operation.
|
|
236
|
+
|
|
237
|
+
### Parameters
|
|
238
|
+
|
|
239
|
+
| Parameter | Type | Required | Description |
|
|
240
|
+
|-----------|------|----------|-------------|
|
|
241
|
+
| `colors` | string[] | ✅ | Array of colors to match (max 50) |
|
|
242
|
+
| `themeCSS` | string | ✅ | CSS containing theme variables |
|
|
243
|
+
| `context` | string | ❌ | Usage context for all colors |
|
|
244
|
+
|
|
245
|
+
### Returns
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
{
|
|
249
|
+
matches: Array<{
|
|
250
|
+
color: string; // Input color
|
|
251
|
+
match: string | null; // Matched variable or null
|
|
252
|
+
confidence: number; // Match confidence
|
|
253
|
+
distance: number; // Perceptual distance
|
|
254
|
+
}>;
|
|
255
|
+
summary: {
|
|
256
|
+
total: number; // Total colors processed
|
|
257
|
+
matched: number; // Successfully matched
|
|
258
|
+
unmatched: number; // No suitable match
|
|
259
|
+
averageConfidence: number;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Examples
|
|
265
|
+
|
|
266
|
+
#### Batch Color Matching
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
{
|
|
270
|
+
"name": "match_theme_colors_batch",
|
|
271
|
+
"arguments": {
|
|
272
|
+
"colors": ["#6366f1", "#ec4899", "#10b981", "#f59e0b"],
|
|
273
|
+
"themeCSS": `
|
|
274
|
+
:root {
|
|
275
|
+
--color-primary: #6366f1;
|
|
276
|
+
--color-pink: #ec4899;
|
|
277
|
+
--color-green: #10b981;
|
|
278
|
+
--color-amber: #f59e0b;
|
|
279
|
+
}
|
|
280
|
+
`
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Response
|
|
285
|
+
{
|
|
286
|
+
"matches": [
|
|
287
|
+
{ "color": "#6366f1", "match": "--color-primary", "confidence": 100 },
|
|
288
|
+
{ "color": "#ec4899", "match": "--color-pink", "confidence": 100 },
|
|
289
|
+
{ "color": "#10b981", "match": "--color-green", "confidence": 100 },
|
|
290
|
+
{ "color": "#f59e0b", "match": "--color-amber", "confidence": 100 }
|
|
291
|
+
],
|
|
292
|
+
"summary": {
|
|
293
|
+
"total": 4,
|
|
294
|
+
"matched": 4,
|
|
295
|
+
"unmatched": 0,
|
|
296
|
+
"averageConfidence": 100
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### Finding Unmatched Colors
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
{
|
|
305
|
+
"name": "match_theme_colors_batch",
|
|
306
|
+
"arguments": {
|
|
307
|
+
"colors": ["#6366f1", "#123456", "#789abc"],
|
|
308
|
+
"themeCSS": ":root { --primary: #6366f1; }"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Shows which colors need variables
|
|
313
|
+
{
|
|
314
|
+
"matches": [
|
|
315
|
+
{ "color": "#6366f1", "match": "--primary", "confidence": 100 },
|
|
316
|
+
{ "color": "#123456", "match": null, "confidence": 0 },
|
|
317
|
+
{ "color": "#789abc", "match": null, "confidence": 0 }
|
|
318
|
+
],
|
|
319
|
+
"summary": {
|
|
320
|
+
"unmatched": 2
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Use Cases
|
|
326
|
+
|
|
327
|
+
- Auditing color usage across a project
|
|
328
|
+
- Finding all unique colors in CSS
|
|
329
|
+
- Identifying colors that need theme variables
|
|
330
|
+
- Bulk color migration
|
|
331
|
+
|
|
332
|
+
## generate_theme_css
|
|
333
|
+
|
|
334
|
+
Generate CSS custom properties for a complete theme from a source color.
|
|
335
|
+
|
|
336
|
+
### Parameters
|
|
337
|
+
|
|
338
|
+
| Parameter | Type | Required | Description |
|
|
339
|
+
|-----------|------|----------|-------------|
|
|
340
|
+
| `sourceColor` | string | ✅ | Source color for theme generation |
|
|
341
|
+
| `prefix` | string | ❌ | Prefix for CSS variables (default: "color") |
|
|
342
|
+
| `includeTones` | number[] | ❌ | Tone values to include (default: Material Design tones) |
|
|
343
|
+
|
|
344
|
+
### Returns
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
{
|
|
348
|
+
css: string; // Generated CSS with custom properties
|
|
349
|
+
theme: {
|
|
350
|
+
primary: object; // Primary palette
|
|
351
|
+
secondary: object; // Secondary palette
|
|
352
|
+
tertiary: object; // Tertiary palette
|
|
353
|
+
neutral: object; // Neutral palette
|
|
354
|
+
error: object; // Error palette
|
|
355
|
+
};
|
|
356
|
+
variables: string[]; // List of generated variable names
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Examples
|
|
361
|
+
|
|
362
|
+
#### Basic Theme Generation
|
|
363
|
+
|
|
364
|
+
```javascript
|
|
365
|
+
{
|
|
366
|
+
"name": "generate_theme_css",
|
|
367
|
+
"arguments": {
|
|
368
|
+
"sourceColor": "#6366f1"
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Generates
|
|
373
|
+
:root {
|
|
374
|
+
/* Primary palette */
|
|
375
|
+
--color-primary-0: #000000;
|
|
376
|
+
--color-primary-10: #00006e;
|
|
377
|
+
--color-primary-20: #0001ac;
|
|
378
|
+
--color-primary-30: #1e2bdb;
|
|
379
|
+
--color-primary-40: #4046f4;
|
|
380
|
+
--color-primary-50: #6366f1;
|
|
381
|
+
--color-primary-60: #7f81ff;
|
|
382
|
+
--color-primary-70: #9da0ff;
|
|
383
|
+
--color-primary-80: #bcc0ff;
|
|
384
|
+
--color-primary-90: #dee0ff;
|
|
385
|
+
--color-primary-95: #eff0ff;
|
|
386
|
+
--color-primary-99: #fffbff;
|
|
387
|
+
--color-primary-100: #ffffff;
|
|
388
|
+
|
|
389
|
+
/* Secondary, tertiary, neutral, error palettes... */
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
#### Custom Prefix and Tones
|
|
394
|
+
|
|
395
|
+
```javascript
|
|
396
|
+
{
|
|
397
|
+
"name": "generate_theme_css",
|
|
398
|
+
"arguments": {
|
|
399
|
+
"sourceColor": "#6366f1",
|
|
400
|
+
"prefix": "theme",
|
|
401
|
+
"includeTones": [0, 25, 50, 75, 100]
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Generates with custom prefix
|
|
406
|
+
:root {
|
|
407
|
+
--theme-primary-0: #000000;
|
|
408
|
+
--theme-primary-25: #0f15c5;
|
|
409
|
+
--theme-primary-50: #6366f1;
|
|
410
|
+
--theme-primary-75: #a1a3ff;
|
|
411
|
+
--theme-primary-100: #ffffff;
|
|
412
|
+
/* ... */
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Use Cases
|
|
417
|
+
|
|
418
|
+
- Creating new design systems
|
|
419
|
+
- Generating Material Design themes
|
|
420
|
+
- Building accessible color palettes
|
|
421
|
+
- Creating consistent color systems
|
|
422
|
+
|
|
423
|
+
## Best Practices
|
|
424
|
+
|
|
425
|
+
### Theme Variable Naming
|
|
426
|
+
|
|
427
|
+
Use clear, semantic names:
|
|
428
|
+
|
|
429
|
+
```css
|
|
430
|
+
/* Good */
|
|
431
|
+
--color-primary-500
|
|
432
|
+
--color-text-primary
|
|
433
|
+
--color-surface-elevated
|
|
434
|
+
|
|
435
|
+
/* Avoid */
|
|
436
|
+
--blue
|
|
437
|
+
--color1
|
|
438
|
+
--my-color
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Confidence Thresholds
|
|
442
|
+
|
|
443
|
+
| Use Case | Recommended | Rationale |
|
|
444
|
+
|----------|-------------|-----------|
|
|
445
|
+
| Production | 85-100% | Avoid false matches |
|
|
446
|
+
| Development | 70-85% | Balance accuracy/coverage |
|
|
447
|
+
| Exploration | 50-70% | Find possibilities |
|
|
448
|
+
|
|
449
|
+
### Performance Tips
|
|
450
|
+
|
|
451
|
+
1. **Cache theme CSS** when doing multiple operations
|
|
452
|
+
2. **Batch color matching** instead of individual calls
|
|
453
|
+
3. **Pre-process theme** to extract variables once
|
|
454
|
+
4. **Use appropriate confidence** to avoid unnecessary processing
|
|
455
|
+
|
|
456
|
+
### Error Handling
|
|
457
|
+
|
|
458
|
+
```javascript
|
|
459
|
+
// Handle no matches
|
|
460
|
+
const result = await matchThemeColor(color, theme);
|
|
461
|
+
if (result.confidence < minConfidence) {
|
|
462
|
+
// Create new variable or keep original
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Handle invalid CSS
|
|
466
|
+
try {
|
|
467
|
+
const refactored = await refactorCSS(css, theme);
|
|
468
|
+
} catch (error) {
|
|
469
|
+
console.error('Invalid CSS:', error);
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Common Patterns
|
|
474
|
+
|
|
475
|
+
### Progressive Enhancement
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
// 1. Start with exact matches
|
|
479
|
+
let confidence = 100;
|
|
480
|
+
let result = match(color, theme, confidence);
|
|
481
|
+
|
|
482
|
+
// 2. Gradually lower threshold
|
|
483
|
+
while (!result && confidence > 50) {
|
|
484
|
+
confidence -= 10;
|
|
485
|
+
result = match(color, theme, confidence);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// 3. Create new variable if needed
|
|
489
|
+
if (!result) {
|
|
490
|
+
createNewVariable(color);
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Theme Validation
|
|
495
|
+
|
|
496
|
+
```javascript
|
|
497
|
+
// Check all theme colors are unique
|
|
498
|
+
const colors = extractThemeColors(themeCSS);
|
|
499
|
+
const unique = new Set(colors.values());
|
|
500
|
+
if (unique.size < colors.size) {
|
|
501
|
+
console.warn('Duplicate colors in theme');
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Migration Workflow
|
|
506
|
+
|
|
507
|
+
```javascript
|
|
508
|
+
// 1. Extract all colors from existing CSS
|
|
509
|
+
const colors = findAllColors(css);
|
|
510
|
+
|
|
511
|
+
// 2. Generate theme from primary color
|
|
512
|
+
const theme = generateTheme(colors[0]);
|
|
513
|
+
|
|
514
|
+
// 3. Match remaining colors
|
|
515
|
+
const matches = matchBatch(colors, theme);
|
|
516
|
+
|
|
517
|
+
// 4. Refactor CSS with theme
|
|
518
|
+
const refactored = refactorWithTheme(css, theme);
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
## Troubleshooting
|
|
522
|
+
|
|
523
|
+
### Low Confidence Matches
|
|
524
|
+
|
|
525
|
+
**Problem**: All matches have low confidence
|
|
526
|
+
**Solution**:
|
|
527
|
+
- Check theme has enough color variations
|
|
528
|
+
- Lower minConfidence threshold
|
|
529
|
+
- Add more theme variables
|
|
530
|
+
|
|
531
|
+
### Wrong Semantic Matches
|
|
532
|
+
|
|
533
|
+
**Problem**: Colors match wrong semantic role
|
|
534
|
+
**Solution**:
|
|
535
|
+
- Use clearer variable naming
|
|
536
|
+
- Provide context parameter
|
|
537
|
+
- Adjust semantic weight in matching
|
|
538
|
+
|
|
539
|
+
### Performance Issues
|
|
540
|
+
|
|
541
|
+
**Problem**: Slow with large CSS files
|
|
542
|
+
**Solution**:
|
|
543
|
+
- Split CSS into smaller chunks
|
|
544
|
+
- Use batch operations
|
|
545
|
+
- Cache parsed theme variables
|
|
546
|
+
|
|
547
|
+
## See Also
|
|
548
|
+
|
|
549
|
+
- [Theme Matching Concepts](../concepts/theme-matching.md) - How matching works
|
|
550
|
+
- [CSS Refactoring Examples](../examples/css-refactoring.md) - Practical examples
|
|
551
|
+
- [Material Design Tools](./material-design.md) - Theme generation
|
|
552
|
+
- [Color Operations](./color-operations.md) - Basic color tools
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import eslint from "@eslint/js";
|
|
2
|
+
import eslintConfigPrettier from "eslint-config-prettier/flat";
|
|
3
|
+
import perfectionist from "eslint-plugin-perfectionist";
|
|
4
|
+
import tseslint from "typescript-eslint";
|
|
5
|
+
|
|
6
|
+
export default tseslint.config(
|
|
7
|
+
eslint.configs.recommended,
|
|
8
|
+
tseslint.configs.recommended,
|
|
9
|
+
perfectionist.configs["recommended-alphabetical"],
|
|
10
|
+
eslintConfigPrettier,
|
|
11
|
+
{
|
|
12
|
+
ignores: ["**/*.js", "dist/**"],
|
|
13
|
+
},
|
|
14
|
+
);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Theme Color Matching Examples
|
|
2
|
+
|
|
3
|
+
## Generate Theme CSS from Source Color
|
|
4
|
+
|
|
5
|
+
Generate a complete Material Design 3 theme with CSS variables:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Using the MCP tool
|
|
9
|
+
generate_theme_css --sourceColor "#6750a4"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
This generates:
|
|
13
|
+
|
|
14
|
+
- Primary, secondary, tertiary palettes (tones 0-100)
|
|
15
|
+
- Error, neutral, and neutral variant palettes
|
|
16
|
+
- Semantic color mappings for light theme
|
|
17
|
+
|
|
18
|
+
## Match Legacy Colors to Theme Variables
|
|
19
|
+
|
|
20
|
+
Find the closest theme variable for a legacy color:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Match a single color
|
|
24
|
+
match_theme_color --color "#6850a0" --themeCSS ":root { --color-primary-40: #6750a4; }"
|
|
25
|
+
|
|
26
|
+
# Result:
|
|
27
|
+
# Variable: --color-primary-40
|
|
28
|
+
# Confidence: 95%
|
|
29
|
+
# Distance: 2.3
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Refactor CSS with Theme Variables
|
|
33
|
+
|
|
34
|
+
Automatically replace hardcoded colors with theme variables:
|
|
35
|
+
|
|
36
|
+
### Input CSS:
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
.button {
|
|
40
|
+
background-color: #6750a4;
|
|
41
|
+
color: #fffbfe;
|
|
42
|
+
border: 1px solid #79747e;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Theme CSS:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
:root {
|
|
50
|
+
--color-primary-40: #6750a4;
|
|
51
|
+
--color-surface-99: #fffbfe;
|
|
52
|
+
--color-outline-50: #79747e;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Refactored Output:
|
|
57
|
+
|
|
58
|
+
```css
|
|
59
|
+
.button {
|
|
60
|
+
background-color: var(--color-primary-40);
|
|
61
|
+
color: var(--color-surface-99);
|
|
62
|
+
border: 1px solid var(--color-outline-50);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Context-Aware Matching
|
|
67
|
+
|
|
68
|
+
The matcher considers usage context for better results:
|
|
69
|
+
|
|
70
|
+
- **text**: Prefers high-contrast colors
|
|
71
|
+
- **background**: Prefers surface colors
|
|
72
|
+
- **border**: Prefers outline colors
|
|
73
|
+
- **shadow**: Prefers shadow colors
|
|
74
|
+
- **accent**: Prefers primary/secondary colors
|
|
75
|
+
|
|
76
|
+
## Batch Color Matching
|
|
77
|
+
|
|
78
|
+
Match multiple colors at once:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
match_theme_colors_batch --colors ["#6750a4", "#ba1a1a", "#ffffff"] --themeCSS "..."
|
|
82
|
+
|
|
83
|
+
# Result:
|
|
84
|
+
# #6750a4 → --color-primary-40 (100%)
|
|
85
|
+
# #ba1a1a → --color-error-40 (100%)
|
|
86
|
+
# #ffffff → --color-surface-100 (100%)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Key Features
|
|
90
|
+
|
|
91
|
+
### HCT Color Space
|
|
92
|
+
|
|
93
|
+
- Uses Google's HCT (Hue, Chroma, Tone) for perceptually uniform color matching
|
|
94
|
+
- Better than LAB for UI applications
|
|
95
|
+
- Tone differences guarantee specific contrast ratios
|
|
96
|
+
|
|
97
|
+
### Multi-Factor Scoring
|
|
98
|
+
|
|
99
|
+
- **Perceptual Distance (60%)**: How visually similar the colors are
|
|
100
|
+
- **Semantic Context (20%)**: Whether the color role matches the usage
|
|
101
|
+
- **Accessibility (20%)**: Contrast ratio considerations
|
|
102
|
+
|
|
103
|
+
### Accessibility Validation
|
|
104
|
+
|
|
105
|
+
- Automatic WCAG contrast checking
|
|
106
|
+
- Warns about potential accessibility issues
|
|
107
|
+
- Suggests alternatives when contrast is insufficient
|
|
108
|
+
|
|
109
|
+
### Material Design Integration
|
|
110
|
+
|
|
111
|
+
- Generates Material Design 3 compliant themes
|
|
112
|
+
- Supports all Material color roles
|
|
113
|
+
- Includes tonal palettes with standard Material tones
|
package/jsr.json
ADDED