@castandcrew/spotlight-mcp 0.1.4 → 0.1.5
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 +37 -43
- package/data/index.json +36016 -42627
- package/dist/tools/get_token.js +2 -1
- package/dist/tools/get_token.js.map +1 -1
- package/dist/tools/search_tokens.js +34 -8
- package/dist/tools/search_tokens.js.map +1 -1
- package/dist/types.d.ts +11 -0
- package/package.json +1 -1
package/dist/tools/get_token.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { guardedIndex } from './_guard.js';
|
|
3
3
|
export function registerGetToken(server) {
|
|
4
|
-
server.tool('get_token', 'Get details for a Spotlight design token: its value, category,
|
|
4
|
+
server.tool('get_token', 'Get details for a Spotlight design token: its default (light/:root) value, category, which components use it, ' +
|
|
5
|
+
'and its variants — the dark-theme value (.spotlight_theme-dark), interactive-state values, etc.', { name: z.string().describe('Token name, e.g. "--space-md", "--color-background-positive"') }, async ({ name }) => {
|
|
5
6
|
const { index, error } = guardedIndex('get_token', 'tokens');
|
|
6
7
|
if (error)
|
|
7
8
|
return error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_token.js","sourceRoot":"","sources":["../../src/tools/get_token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,IAAI,CACT,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"get_token.js","sourceRoot":"","sources":["../../src/tools/get_token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,IAAI,CACT,WAAW,EACX,gHAAgH;QAChH,iGAAiG,EACjG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC,EAAE,EAC7F,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC7D,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAC7B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CACjD,CAAC;QACF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,IAAI,yBAAyB,KAAK,CAAC,MAAM,CAAC,MAAM,wEAAwE,EAAE,CAAC;gBAC9K,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC3E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -4,30 +4,56 @@ import { guardedIndex } from './_guard.js';
|
|
|
4
4
|
import { searchOrPerTerm } from './_fuzzy.js';
|
|
5
5
|
import { expandWithSynonyms } from './_synonyms.js';
|
|
6
6
|
export function registerSearchTokens(server) {
|
|
7
|
-
server.tool('search_tokens', 'Search Spotlight design tokens by name, description, or
|
|
7
|
+
server.tool('search_tokens', 'Search Spotlight design tokens by name, description, category, or value (light and dark). ' +
|
|
8
|
+
'Returns purpose-named semantic tokens; pass includeRefs to also get raw palette/scale steps.', {
|
|
8
9
|
query: z.string().describe('Semantic description, e.g. "large spacing", "positive color", "border radius"'),
|
|
9
|
-
category: z.string().optional().describe('
|
|
10
|
+
category: z.string().optional().describe('Substring filter on the token category: "color-background", "color-text", "color-border", "color-content", ' +
|
|
11
|
+
'"space", "size", "border-radius", "text-size", "text-weight", "text-line-height". ' +
|
|
12
|
+
'Layers (semantic/foundation/ref) are not categories — leave this out to search all tokens.'),
|
|
10
13
|
limit: z.number().optional().default(10).describe('Max results to return (default 10)'),
|
|
11
|
-
|
|
14
|
+
includeRefs: z.boolean().optional().default(false)
|
|
15
|
+
.describe('Also return ref-layer tokens (numbered palette/scale steps like --color-system-100). Default false.'),
|
|
16
|
+
}, async ({ query, category, limit, includeRefs }) => {
|
|
12
17
|
const { index, error } = guardedIndex('search_tokens', 'tokens');
|
|
13
18
|
if (error)
|
|
14
19
|
return error;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
// A query that spells a token name is a lookup: let it reach ref tokens too.
|
|
21
|
+
const refsOk = includeRefs || query.includes('--');
|
|
22
|
+
const tokens = index.tokens.filter(t => (refsOk || t.layer !== 'ref') &&
|
|
23
|
+
(!category || t.category.toLowerCase().includes(category.toLowerCase())));
|
|
18
24
|
const fuse = new Fuse(tokens, {
|
|
19
|
-
keys: [
|
|
25
|
+
keys: [
|
|
26
|
+
'name', 'useCase', 'description', 'category', 'variant', 'property',
|
|
27
|
+
{ name: 'value', weight: 0.5 }, { name: 'variants.value', weight: 0.5 },
|
|
28
|
+
],
|
|
20
29
|
threshold: 0.4,
|
|
21
30
|
ignoreLocation: true,
|
|
22
31
|
includeScore: true,
|
|
23
32
|
});
|
|
24
33
|
const expandedQuery = expandWithSynonyms(query);
|
|
25
|
-
|
|
34
|
+
// With ~700 semantic tokens many results tie at a perfect Fuse score (the
|
|
35
|
+
// query fuzzy-matches a useCase/description), and ties come back in index
|
|
36
|
+
// order — so "page background" buried --color-background-page under
|
|
37
|
+
// interactive-selected tokens. Within a score bucket, prefer results whose
|
|
38
|
+
// *name* spells more of the query's terms. Only a tie-break: a global
|
|
39
|
+
// name-term sort would rank --text-p-spacing-* over --space-lg for
|
|
40
|
+
// "large spacing" just because "spacing" is in the name.
|
|
41
|
+
const terms = expandedQuery.toLowerCase().split(/\s+/).filter(t => t.length >= 3);
|
|
42
|
+
const nameHits = (name) => terms.filter(t => name.toLowerCase().includes(t)).length;
|
|
43
|
+
const bucket = (score) => Math.round((score ?? 1) * 100);
|
|
44
|
+
const results = searchOrPerTerm(fuse, expandedQuery, Math.max(limit * 5, 50))
|
|
45
|
+
.sort((a, b) => bucket(a.score) - bucket(b.score) || nameHits(b.item.name) - nameHits(a.item.name))
|
|
46
|
+
.slice(0, limit)
|
|
47
|
+
.map(r => ({
|
|
26
48
|
name: r.item.name,
|
|
27
49
|
value: r.item.value,
|
|
28
50
|
category: r.item.category,
|
|
29
51
|
layer: r.item.layer,
|
|
30
52
|
useCase: r.item.useCase,
|
|
53
|
+
...(r.item.description && { description: r.item.description }),
|
|
54
|
+
...(r.item.variants?.some(v => v.appliesTo.includes('.spotlight_theme-dark')) && {
|
|
55
|
+
darkValue: r.item.variants.find(v => v.appliesTo.includes('.spotlight_theme-dark')).value,
|
|
56
|
+
}),
|
|
31
57
|
score: r.score,
|
|
32
58
|
}));
|
|
33
59
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search_tokens.js","sourceRoot":"","sources":["../../src/tools/search_tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"search_tokens.js","sourceRoot":"","sources":["../../src/tools/search_tokens.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -71,6 +71,17 @@ export interface Token {
|
|
|
71
71
|
appliesTo?: string[];
|
|
72
72
|
/** Human-readable intent derived from the name formula — "what to use this for". */
|
|
73
73
|
useCase?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Other values the same name resolves to under other selectors — the dark
|
|
76
|
+
* theme (`.spotlight_theme-dark`), interactive states, emphasis classes.
|
|
77
|
+
* `value` is always the default (`:root`) value; see SPT-1896.
|
|
78
|
+
*/
|
|
79
|
+
variants?: TokenVariant[];
|
|
80
|
+
}
|
|
81
|
+
export interface TokenVariant {
|
|
82
|
+
/** Selectors under which this value applies, e.g. [".spotlight_theme-dark"]. */
|
|
83
|
+
appliesTo: string[];
|
|
84
|
+
value: string;
|
|
74
85
|
}
|
|
75
86
|
export interface Pattern {
|
|
76
87
|
id: string;
|