@capybara-hq/plugin-sdk 0.1.0-rc.6 → 0.1.0-rc.8
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/agent-docs/connector-templates.md +1 -0
- package/agent-docs/plugin-format.md +17 -2
- package/dist/cards.d.ts +7 -0
- package/dist/cards.js +4 -4
- package/dist/channel.d.ts +20 -1
- package/dist/connector-auth.d.ts +2 -0
- package/dist/connector-auth.js +15 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/marketplace.d.ts +26 -0
- package/dist/marketplace.js +43 -1
- package/dist/plugin-manifest.d.ts +22 -3
- package/dist/plugin-manifest.js +85 -5
- package/dist/setup-guide.d.ts +94 -0
- package/dist/setup-guide.js +135 -0
- package/dist/theme-assets.d.ts +39 -0
- package/dist/theme-assets.js +449 -0
- package/dist/theme-readability.d.ts +37 -0
- package/dist/theme-readability.js +145 -0
- package/dist/theme-tokens.generated.d.ts +275 -0
- package/dist/theme-tokens.generated.js +167 -0
- package/dist/theme.d.ts +152 -0
- package/dist/theme.js +392 -0
- package/package.json +2 -1
- package/schemas/connector-template.v1.schema.json +3 -0
- package/schemas/marketplace.v1.schema.json +14 -0
- package/schemas/plugin.v1.schema.json +155 -0
- package/schemas/theme.v1.schema.json +225 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/** The built-in token values a theme overrides (design spec §2). */
|
|
2
|
+
export declare const THEME_TOKENS: {
|
|
3
|
+
readonly color: {
|
|
4
|
+
readonly bg: {
|
|
5
|
+
readonly dark: "#0A0A0A";
|
|
6
|
+
readonly light: "#FAF9F6";
|
|
7
|
+
};
|
|
8
|
+
readonly panel: {
|
|
9
|
+
readonly dark: "#111110";
|
|
10
|
+
readonly light: "#FFFFFF";
|
|
11
|
+
};
|
|
12
|
+
readonly "panel-2": {
|
|
13
|
+
readonly dark: "#0E0E0D";
|
|
14
|
+
readonly light: "#FCFBF9";
|
|
15
|
+
};
|
|
16
|
+
readonly sidebar: {
|
|
17
|
+
readonly dark: "#111110";
|
|
18
|
+
readonly light: "#F3F2EE";
|
|
19
|
+
};
|
|
20
|
+
readonly "sidebar-active": {
|
|
21
|
+
readonly dark: "#1A1A18";
|
|
22
|
+
readonly light: "rgba(26,26,24,0.09)";
|
|
23
|
+
};
|
|
24
|
+
readonly raised: {
|
|
25
|
+
readonly dark: "#141413";
|
|
26
|
+
readonly light: "#FFFFFF";
|
|
27
|
+
};
|
|
28
|
+
readonly selected: {
|
|
29
|
+
readonly dark: "#1F1F1D";
|
|
30
|
+
readonly light: "rgba(26,26,24,0.07)";
|
|
31
|
+
};
|
|
32
|
+
readonly hover: {
|
|
33
|
+
readonly dark: "#171716";
|
|
34
|
+
readonly light: "rgba(26,26,24,0.04)";
|
|
35
|
+
};
|
|
36
|
+
readonly "line-soft": {
|
|
37
|
+
readonly dark: "#1C1C1A";
|
|
38
|
+
readonly light: "#E8E7E2";
|
|
39
|
+
};
|
|
40
|
+
readonly line: {
|
|
41
|
+
readonly dark: "#2A2A28";
|
|
42
|
+
readonly light: "#D9D8D2";
|
|
43
|
+
};
|
|
44
|
+
readonly "line-strong": {
|
|
45
|
+
readonly dark: "#3A3A37";
|
|
46
|
+
readonly light: "#B5B5AE";
|
|
47
|
+
};
|
|
48
|
+
readonly "line-card": {
|
|
49
|
+
readonly dark: "rgba(255,255,255,0.08)";
|
|
50
|
+
readonly light: "rgba(26,26,24,0.07)";
|
|
51
|
+
};
|
|
52
|
+
readonly "scroll-thumb": {
|
|
53
|
+
readonly dark: "rgba(255,255,255,0.15)";
|
|
54
|
+
readonly light: "rgba(26,26,24,0.20)";
|
|
55
|
+
};
|
|
56
|
+
readonly ink: {
|
|
57
|
+
readonly dark: "#E6E6E3";
|
|
58
|
+
readonly light: "#1A1A18";
|
|
59
|
+
};
|
|
60
|
+
readonly muted: {
|
|
61
|
+
readonly dark: "#8E8E89";
|
|
62
|
+
readonly light: "#5E5E5A";
|
|
63
|
+
};
|
|
64
|
+
readonly faint: {
|
|
65
|
+
readonly dark: "#5A5A56";
|
|
66
|
+
readonly light: "#9A9A94";
|
|
67
|
+
};
|
|
68
|
+
readonly disabled: {
|
|
69
|
+
readonly dark: "#6E6E69";
|
|
70
|
+
readonly light: "#82827C";
|
|
71
|
+
};
|
|
72
|
+
readonly accent: {
|
|
73
|
+
readonly dark: "#FF6A13";
|
|
74
|
+
readonly light: "#CC4609";
|
|
75
|
+
};
|
|
76
|
+
readonly "accent-hover": {
|
|
77
|
+
readonly dark: "#FF8240";
|
|
78
|
+
readonly light: "#B83F08";
|
|
79
|
+
};
|
|
80
|
+
readonly "accent-press": {
|
|
81
|
+
readonly dark: "#E85A08";
|
|
82
|
+
readonly light: "#A33707";
|
|
83
|
+
};
|
|
84
|
+
readonly "on-accent": {
|
|
85
|
+
readonly dark: "#0A0A0A";
|
|
86
|
+
readonly light: "#FFFFFF";
|
|
87
|
+
};
|
|
88
|
+
readonly "accent-tint": {
|
|
89
|
+
readonly dark: "color-mix(in srgb, var(--cb-accent) 12%, transparent)";
|
|
90
|
+
readonly light: "color-mix(in srgb, var(--cb-accent) 12%, transparent)";
|
|
91
|
+
};
|
|
92
|
+
readonly "focus-ring": {
|
|
93
|
+
readonly dark: "rgba(255,106,19,.25)";
|
|
94
|
+
readonly light: "rgba(204,70,9,.18)";
|
|
95
|
+
};
|
|
96
|
+
readonly ok: {
|
|
97
|
+
readonly dark: "#3FD483";
|
|
98
|
+
readonly light: "#16803F";
|
|
99
|
+
};
|
|
100
|
+
readonly fail: {
|
|
101
|
+
readonly dark: "#FF5C52";
|
|
102
|
+
readonly light: "#C8302A";
|
|
103
|
+
};
|
|
104
|
+
readonly warn: {
|
|
105
|
+
readonly dark: "#F2C14B";
|
|
106
|
+
readonly light: "#8F6500";
|
|
107
|
+
};
|
|
108
|
+
readonly scrim: {
|
|
109
|
+
readonly dark: "rgba(0,0,0,.60)";
|
|
110
|
+
readonly light: "rgba(10,10,10,.25)";
|
|
111
|
+
};
|
|
112
|
+
readonly "diff-add": {
|
|
113
|
+
readonly dark: "rgba(63,212,131,.08)";
|
|
114
|
+
readonly light: "rgba(22,128,63,.10)";
|
|
115
|
+
};
|
|
116
|
+
readonly "diff-del": {
|
|
117
|
+
readonly dark: "rgba(255,92,82,.08)";
|
|
118
|
+
readonly light: "rgba(207,34,46,.08)";
|
|
119
|
+
};
|
|
120
|
+
readonly "avatar-black": {
|
|
121
|
+
readonly dark: "#1C1C1A";
|
|
122
|
+
readonly light: "#1C1C1A";
|
|
123
|
+
};
|
|
124
|
+
readonly "avatar-white": {
|
|
125
|
+
readonly dark: "#F2F2EE";
|
|
126
|
+
readonly light: "#FFFFFF";
|
|
127
|
+
};
|
|
128
|
+
readonly "avatar-capybara-ground": {
|
|
129
|
+
readonly dark: "#3D2213";
|
|
130
|
+
readonly light: "#FBE3D2";
|
|
131
|
+
};
|
|
132
|
+
readonly "avatar-black-bear-ground": {
|
|
133
|
+
readonly dark: "#9C8468";
|
|
134
|
+
readonly light: "#E6D6C1";
|
|
135
|
+
};
|
|
136
|
+
readonly "avatar-black-bear-snout": {
|
|
137
|
+
readonly dark: "#C9A074";
|
|
138
|
+
readonly light: "#C49A6C";
|
|
139
|
+
};
|
|
140
|
+
readonly "avatar-panda-ground": {
|
|
141
|
+
readonly dark: "#5E9168";
|
|
142
|
+
readonly light: "#669D71";
|
|
143
|
+
};
|
|
144
|
+
readonly "avatar-elephant-ground": {
|
|
145
|
+
readonly dark: "#2A2838";
|
|
146
|
+
readonly light: "#E6E3F2";
|
|
147
|
+
};
|
|
148
|
+
readonly "avatar-elephant": {
|
|
149
|
+
readonly dark: "#9AA0A8";
|
|
150
|
+
readonly light: "#757B84";
|
|
151
|
+
};
|
|
152
|
+
readonly "avatar-elephant-ear": {
|
|
153
|
+
readonly dark: "#7D838C";
|
|
154
|
+
readonly light: "#5A6068";
|
|
155
|
+
};
|
|
156
|
+
readonly "avatar-fox-ground": {
|
|
157
|
+
readonly dark: "#3A2414";
|
|
158
|
+
readonly light: "#FCEBD9";
|
|
159
|
+
};
|
|
160
|
+
readonly "avatar-fox": {
|
|
161
|
+
readonly dark: "#F07A2E";
|
|
162
|
+
readonly light: "#D8601A";
|
|
163
|
+
};
|
|
164
|
+
readonly "avatar-fox-ear": {
|
|
165
|
+
readonly dark: "#8A3E16";
|
|
166
|
+
readonly light: "#7A3310";
|
|
167
|
+
};
|
|
168
|
+
readonly "avatar-owl-ground": {
|
|
169
|
+
readonly dark: "#2E2618";
|
|
170
|
+
readonly light: "#EFE6D4";
|
|
171
|
+
};
|
|
172
|
+
readonly "avatar-owl": {
|
|
173
|
+
readonly dark: "#B07D52";
|
|
174
|
+
readonly light: "#875A36";
|
|
175
|
+
};
|
|
176
|
+
readonly "avatar-owl-belly": {
|
|
177
|
+
readonly dark: "#D9B68C";
|
|
178
|
+
readonly light: "#D9B68C";
|
|
179
|
+
};
|
|
180
|
+
readonly "avatar-owl-eye": {
|
|
181
|
+
readonly dark: "#F5C542";
|
|
182
|
+
readonly light: "#F5C542";
|
|
183
|
+
};
|
|
184
|
+
readonly "avatar-beak": {
|
|
185
|
+
readonly dark: "#EE8A2A";
|
|
186
|
+
readonly light: "#EE8A2A";
|
|
187
|
+
};
|
|
188
|
+
readonly "avatar-penguin-ground": {
|
|
189
|
+
readonly dark: "#5F8AAD";
|
|
190
|
+
readonly light: "#6692B6";
|
|
191
|
+
};
|
|
192
|
+
readonly "avatar-rabbit-ground": {
|
|
193
|
+
readonly dark: "#3A2229";
|
|
194
|
+
readonly light: "#F8DDE3";
|
|
195
|
+
};
|
|
196
|
+
readonly "avatar-rabbit": {
|
|
197
|
+
readonly dark: "#B89A84";
|
|
198
|
+
readonly light: "#8F725C";
|
|
199
|
+
};
|
|
200
|
+
readonly "avatar-rabbit-pink": {
|
|
201
|
+
readonly dark: "#F2A7B5";
|
|
202
|
+
readonly light: "#F2A7B5";
|
|
203
|
+
};
|
|
204
|
+
readonly "avatar-turtle-ground": {
|
|
205
|
+
readonly dark: "#2E2A18";
|
|
206
|
+
readonly light: "#F2E8C9";
|
|
207
|
+
};
|
|
208
|
+
readonly "avatar-turtle": {
|
|
209
|
+
readonly dark: "#5FA548";
|
|
210
|
+
readonly light: "#4E8F3A";
|
|
211
|
+
};
|
|
212
|
+
readonly "avatar-turtle-shell": {
|
|
213
|
+
readonly dark: "#3B7330";
|
|
214
|
+
readonly light: "#2F5E24";
|
|
215
|
+
};
|
|
216
|
+
readonly "avatar-turtle-skin": {
|
|
217
|
+
readonly dark: "#A8C66C";
|
|
218
|
+
readonly light: "#9FBF62";
|
|
219
|
+
};
|
|
220
|
+
readonly "avatar-whale-ground": {
|
|
221
|
+
readonly dark: "#16283A";
|
|
222
|
+
readonly light: "#DCEFF5";
|
|
223
|
+
};
|
|
224
|
+
readonly "avatar-whale": {
|
|
225
|
+
readonly dark: "#5A92D6";
|
|
226
|
+
readonly light: "#3A72B5";
|
|
227
|
+
};
|
|
228
|
+
readonly "avatar-whale-belly": {
|
|
229
|
+
readonly dark: "#DCEAF5";
|
|
230
|
+
readonly light: "#FFFFFF";
|
|
231
|
+
};
|
|
232
|
+
readonly "avatar-whale-spout": {
|
|
233
|
+
readonly dark: "#8EC3E8";
|
|
234
|
+
readonly light: "#8EC3E8";
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
readonly shadow: {
|
|
238
|
+
readonly "shadow-1": {
|
|
239
|
+
readonly dark: "0 8px 24px rgba(0,0,0,.40)";
|
|
240
|
+
readonly light: "0 2px 8px rgba(10,10,10,.08)";
|
|
241
|
+
};
|
|
242
|
+
readonly "shadow-2": {
|
|
243
|
+
readonly dark: "0 16px 48px rgba(0,0,0,.50)";
|
|
244
|
+
readonly light: "0 8px 24px rgba(10,10,10,.12)";
|
|
245
|
+
};
|
|
246
|
+
readonly "shadow-sheet": {
|
|
247
|
+
readonly dark: "-16px 0 40px rgba(0,0,0,.40)";
|
|
248
|
+
readonly light: "-4px 0 16px rgba(10,10,10,.08)";
|
|
249
|
+
};
|
|
250
|
+
readonly "shadow-float": {
|
|
251
|
+
readonly dark: "0 8px 24px rgba(0,0,0,.45)";
|
|
252
|
+
readonly light: "0 8px 24px rgba(26,26,24,.08)";
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
readonly radius: {
|
|
256
|
+
readonly sm: 4;
|
|
257
|
+
readonly md: 8;
|
|
258
|
+
readonly bubble: 10;
|
|
259
|
+
};
|
|
260
|
+
};
|
|
261
|
+
/** The built-in font stacks a theme's fonts go in front of: `mono` is `--cb-font`, `prose` `--cb-font-prose`. */
|
|
262
|
+
export declare const THEME_FONTS: {
|
|
263
|
+
readonly mono: "\"Sarasa Mono SC\", ui-monospace, monospace";
|
|
264
|
+
readonly prose: "\"Inter\", \"Source Han Sans SC\", system-ui, sans-serif";
|
|
265
|
+
};
|
|
266
|
+
/** The tokens a theme may override: no avatar colors, no color-mix values (they derive). */
|
|
267
|
+
export declare const THEME_OVERRIDABLE: {
|
|
268
|
+
readonly color: readonly ["bg", "panel", "panel-2", "sidebar", "sidebar-active", "raised", "selected", "hover", "line-soft", "line", "line-strong", "line-card", "scroll-thumb", "ink", "muted", "faint", "disabled", "accent", "accent-hover", "accent-press", "on-accent", "focus-ring", "ok", "fail", "warn", "scrim", "diff-add", "diff-del"];
|
|
269
|
+
readonly shadow: readonly ["shadow-1", "shadow-2", "shadow-sheet", "shadow-float"];
|
|
270
|
+
readonly radius: readonly ["sm", "md", "bubble"];
|
|
271
|
+
};
|
|
272
|
+
/** [foreground, background, floor] or, with a fourth element, the surface it sits on. */
|
|
273
|
+
export declare const THEME_CONTRAST: readonly (readonly [fg: string, bg: string, floor: number, over?: string])[];
|
|
274
|
+
/** [ground, surface, minimum OKLab lightness difference x100]. */
|
|
275
|
+
export declare const THEME_SEPARATION: readonly (readonly [ground: string, surface: string, floor: number])[];
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Generated by pnpm gen:tokens from docs/design/tokens.json; do not edit.
|
|
2
|
+
// biome-ignore-all format: token values stay verbatim (uppercase hex, rgba spelling)
|
|
3
|
+
/** The built-in token values a theme overrides (design spec §2). */
|
|
4
|
+
export const THEME_TOKENS = {
|
|
5
|
+
color: {
|
|
6
|
+
"bg": { dark: "#0A0A0A", light: "#FAF9F6" },
|
|
7
|
+
"panel": { dark: "#111110", light: "#FFFFFF" },
|
|
8
|
+
"panel-2": { dark: "#0E0E0D", light: "#FCFBF9" },
|
|
9
|
+
"sidebar": { dark: "#111110", light: "#F3F2EE" },
|
|
10
|
+
"sidebar-active": { dark: "#1A1A18", light: "rgba(26,26,24,0.09)" },
|
|
11
|
+
"raised": { dark: "#141413", light: "#FFFFFF" },
|
|
12
|
+
"selected": { dark: "#1F1F1D", light: "rgba(26,26,24,0.07)" },
|
|
13
|
+
"hover": { dark: "#171716", light: "rgba(26,26,24,0.04)" },
|
|
14
|
+
"line-soft": { dark: "#1C1C1A", light: "#E8E7E2" },
|
|
15
|
+
"line": { dark: "#2A2A28", light: "#D9D8D2" },
|
|
16
|
+
"line-strong": { dark: "#3A3A37", light: "#B5B5AE" },
|
|
17
|
+
"line-card": { dark: "rgba(255,255,255,0.08)", light: "rgba(26,26,24,0.07)" },
|
|
18
|
+
"scroll-thumb": { dark: "rgba(255,255,255,0.15)", light: "rgba(26,26,24,0.20)" },
|
|
19
|
+
"ink": { dark: "#E6E6E3", light: "#1A1A18" },
|
|
20
|
+
"muted": { dark: "#8E8E89", light: "#5E5E5A" },
|
|
21
|
+
"faint": { dark: "#5A5A56", light: "#9A9A94" },
|
|
22
|
+
"disabled": { dark: "#6E6E69", light: "#82827C" },
|
|
23
|
+
"accent": { dark: "#FF6A13", light: "#CC4609" },
|
|
24
|
+
"accent-hover": { dark: "#FF8240", light: "#B83F08" },
|
|
25
|
+
"accent-press": { dark: "#E85A08", light: "#A33707" },
|
|
26
|
+
"on-accent": { dark: "#0A0A0A", light: "#FFFFFF" },
|
|
27
|
+
"accent-tint": { dark: "color-mix(in srgb, var(--cb-accent) 12%, transparent)", light: "color-mix(in srgb, var(--cb-accent) 12%, transparent)" },
|
|
28
|
+
"focus-ring": { dark: "rgba(255,106,19,.25)", light: "rgba(204,70,9,.18)" },
|
|
29
|
+
"ok": { dark: "#3FD483", light: "#16803F" },
|
|
30
|
+
"fail": { dark: "#FF5C52", light: "#C8302A" },
|
|
31
|
+
"warn": { dark: "#F2C14B", light: "#8F6500" },
|
|
32
|
+
"scrim": { dark: "rgba(0,0,0,.60)", light: "rgba(10,10,10,.25)" },
|
|
33
|
+
"diff-add": { dark: "rgba(63,212,131,.08)", light: "rgba(22,128,63,.10)" },
|
|
34
|
+
"diff-del": { dark: "rgba(255,92,82,.08)", light: "rgba(207,34,46,.08)" },
|
|
35
|
+
"avatar-black": { dark: "#1C1C1A", light: "#1C1C1A" },
|
|
36
|
+
"avatar-white": { dark: "#F2F2EE", light: "#FFFFFF" },
|
|
37
|
+
"avatar-capybara-ground": { dark: "#3D2213", light: "#FBE3D2" },
|
|
38
|
+
"avatar-black-bear-ground": { dark: "#9C8468", light: "#E6D6C1" },
|
|
39
|
+
"avatar-black-bear-snout": { dark: "#C9A074", light: "#C49A6C" },
|
|
40
|
+
"avatar-panda-ground": { dark: "#5E9168", light: "#669D71" },
|
|
41
|
+
"avatar-elephant-ground": { dark: "#2A2838", light: "#E6E3F2" },
|
|
42
|
+
"avatar-elephant": { dark: "#9AA0A8", light: "#757B84" },
|
|
43
|
+
"avatar-elephant-ear": { dark: "#7D838C", light: "#5A6068" },
|
|
44
|
+
"avatar-fox-ground": { dark: "#3A2414", light: "#FCEBD9" },
|
|
45
|
+
"avatar-fox": { dark: "#F07A2E", light: "#D8601A" },
|
|
46
|
+
"avatar-fox-ear": { dark: "#8A3E16", light: "#7A3310" },
|
|
47
|
+
"avatar-owl-ground": { dark: "#2E2618", light: "#EFE6D4" },
|
|
48
|
+
"avatar-owl": { dark: "#B07D52", light: "#875A36" },
|
|
49
|
+
"avatar-owl-belly": { dark: "#D9B68C", light: "#D9B68C" },
|
|
50
|
+
"avatar-owl-eye": { dark: "#F5C542", light: "#F5C542" },
|
|
51
|
+
"avatar-beak": { dark: "#EE8A2A", light: "#EE8A2A" },
|
|
52
|
+
"avatar-penguin-ground": { dark: "#5F8AAD", light: "#6692B6" },
|
|
53
|
+
"avatar-rabbit-ground": { dark: "#3A2229", light: "#F8DDE3" },
|
|
54
|
+
"avatar-rabbit": { dark: "#B89A84", light: "#8F725C" },
|
|
55
|
+
"avatar-rabbit-pink": { dark: "#F2A7B5", light: "#F2A7B5" },
|
|
56
|
+
"avatar-turtle-ground": { dark: "#2E2A18", light: "#F2E8C9" },
|
|
57
|
+
"avatar-turtle": { dark: "#5FA548", light: "#4E8F3A" },
|
|
58
|
+
"avatar-turtle-shell": { dark: "#3B7330", light: "#2F5E24" },
|
|
59
|
+
"avatar-turtle-skin": { dark: "#A8C66C", light: "#9FBF62" },
|
|
60
|
+
"avatar-whale-ground": { dark: "#16283A", light: "#DCEFF5" },
|
|
61
|
+
"avatar-whale": { dark: "#5A92D6", light: "#3A72B5" },
|
|
62
|
+
"avatar-whale-belly": { dark: "#DCEAF5", light: "#FFFFFF" },
|
|
63
|
+
"avatar-whale-spout": { dark: "#8EC3E8", light: "#8EC3E8" },
|
|
64
|
+
},
|
|
65
|
+
shadow: {
|
|
66
|
+
"shadow-1": { dark: "0 8px 24px rgba(0,0,0,.40)", light: "0 2px 8px rgba(10,10,10,.08)" },
|
|
67
|
+
"shadow-2": { dark: "0 16px 48px rgba(0,0,0,.50)", light: "0 8px 24px rgba(10,10,10,.12)" },
|
|
68
|
+
"shadow-sheet": { dark: "-16px 0 40px rgba(0,0,0,.40)", light: "-4px 0 16px rgba(10,10,10,.08)" },
|
|
69
|
+
"shadow-float": { dark: "0 8px 24px rgba(0,0,0,.45)", light: "0 8px 24px rgba(26,26,24,.08)" },
|
|
70
|
+
},
|
|
71
|
+
radius: { sm: 4, md: 8, bubble: 10 },
|
|
72
|
+
};
|
|
73
|
+
/** The built-in font stacks a theme's fonts go in front of: `mono` is `--cb-font`, `prose` `--cb-font-prose`. */
|
|
74
|
+
export const THEME_FONTS = {
|
|
75
|
+
mono: "\"Sarasa Mono SC\", ui-monospace, monospace",
|
|
76
|
+
prose: "\"Inter\", \"Source Han Sans SC\", system-ui, sans-serif",
|
|
77
|
+
};
|
|
78
|
+
/** The tokens a theme may override: no avatar colors, no color-mix values (they derive). */
|
|
79
|
+
export const THEME_OVERRIDABLE = {
|
|
80
|
+
color: [
|
|
81
|
+
"bg",
|
|
82
|
+
"panel",
|
|
83
|
+
"panel-2",
|
|
84
|
+
"sidebar",
|
|
85
|
+
"sidebar-active",
|
|
86
|
+
"raised",
|
|
87
|
+
"selected",
|
|
88
|
+
"hover",
|
|
89
|
+
"line-soft",
|
|
90
|
+
"line",
|
|
91
|
+
"line-strong",
|
|
92
|
+
"line-card",
|
|
93
|
+
"scroll-thumb",
|
|
94
|
+
"ink",
|
|
95
|
+
"muted",
|
|
96
|
+
"faint",
|
|
97
|
+
"disabled",
|
|
98
|
+
"accent",
|
|
99
|
+
"accent-hover",
|
|
100
|
+
"accent-press",
|
|
101
|
+
"on-accent",
|
|
102
|
+
"focus-ring",
|
|
103
|
+
"ok",
|
|
104
|
+
"fail",
|
|
105
|
+
"warn",
|
|
106
|
+
"scrim",
|
|
107
|
+
"diff-add",
|
|
108
|
+
"diff-del",
|
|
109
|
+
],
|
|
110
|
+
shadow: [
|
|
111
|
+
"shadow-1",
|
|
112
|
+
"shadow-2",
|
|
113
|
+
"shadow-sheet",
|
|
114
|
+
"shadow-float",
|
|
115
|
+
],
|
|
116
|
+
radius: ["sm", "md", "bubble"],
|
|
117
|
+
};
|
|
118
|
+
/** [foreground, background, floor] or, with a fourth element, the surface it sits on. */
|
|
119
|
+
export const THEME_CONTRAST = [
|
|
120
|
+
["ink", "bg", 4.5],
|
|
121
|
+
["muted", "bg", 4.5],
|
|
122
|
+
["muted", "panel", 4.5],
|
|
123
|
+
["muted", "sidebar", 4.5],
|
|
124
|
+
["muted", "panel-2", 4.5],
|
|
125
|
+
["muted", "raised", 4.5],
|
|
126
|
+
["muted", "selected", 4.5],
|
|
127
|
+
["muted", "hover", 4.5],
|
|
128
|
+
["disabled", "bg", 3],
|
|
129
|
+
["disabled", "panel", 3],
|
|
130
|
+
["disabled", "hover", 3],
|
|
131
|
+
["disabled", "selected", 3],
|
|
132
|
+
["ink", "sidebar-active", 4.5],
|
|
133
|
+
["muted", "selected", 4.5, "sidebar"],
|
|
134
|
+
["muted", "hover", 4.5, "sidebar"],
|
|
135
|
+
["ink", "sidebar-active", 4.5, "sidebar"],
|
|
136
|
+
["on-accent", "accent", 4.5],
|
|
137
|
+
["fail", "bg", 4.5],
|
|
138
|
+
["warn", "bg", 4.5],
|
|
139
|
+
["fail", "panel", 4.5],
|
|
140
|
+
["warn", "panel", 4.5],
|
|
141
|
+
["accent", "bg", 3],
|
|
142
|
+
["line", "bg", 1],
|
|
143
|
+
["ink", "diff-add", 4.5],
|
|
144
|
+
["ink", "diff-del", 4.5],
|
|
145
|
+
["accent", "avatar-capybara-ground", 3],
|
|
146
|
+
["avatar-black", "avatar-black-bear-ground", 3],
|
|
147
|
+
["avatar-black", "avatar-panda-ground", 3],
|
|
148
|
+
["avatar-elephant", "avatar-elephant-ground", 3],
|
|
149
|
+
["avatar-fox", "avatar-fox-ground", 3],
|
|
150
|
+
["avatar-owl", "avatar-owl-ground", 3],
|
|
151
|
+
["avatar-black", "avatar-penguin-ground", 3],
|
|
152
|
+
["avatar-rabbit", "avatar-rabbit-ground", 3],
|
|
153
|
+
["avatar-turtle", "avatar-turtle-ground", 3],
|
|
154
|
+
["avatar-whale", "avatar-whale-ground", 3],
|
|
155
|
+
["avatar-white", "avatar-panda-ground", 3],
|
|
156
|
+
["avatar-white", "avatar-penguin-ground", 3],
|
|
157
|
+
];
|
|
158
|
+
/** [ground, surface, minimum OKLab lightness difference x100]. */
|
|
159
|
+
export const THEME_SEPARATION = [
|
|
160
|
+
["hover", "bg", 2.5],
|
|
161
|
+
["hover", "panel", 2.5],
|
|
162
|
+
["hover", "sidebar", 2.5],
|
|
163
|
+
["selected", "bg", 2.5],
|
|
164
|
+
["selected", "panel", 2.5],
|
|
165
|
+
["selected", "sidebar", 2.5],
|
|
166
|
+
["sidebar-active", "sidebar", 2.5],
|
|
167
|
+
];
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type LocalizedName } from "./plugin-package.js";
|
|
3
|
+
import { type MergedScheme, type ThemeScheme } from "./theme-readability.js";
|
|
4
|
+
/**
|
|
5
|
+
* A theme file `themes/<id>.json` (themes spec §4): a partial override of the design tokens per
|
|
6
|
+
* scheme, optional fonts and an optional logo. The id is the file's base name
|
|
7
|
+
* ({@link themeIdOf}, `CATALOG_ITEM_NAME_RE`).
|
|
8
|
+
*
|
|
9
|
+
* {@link parseThemeFile} is the CSS-injection boundary: every token value is parsed against the
|
|
10
|
+
* grammar `tokens.json` uses (`#RRGGBB`, `rgba(r,g,b,a)`, shadows `<x> <y> <blur> [<spread>]
|
|
11
|
+
* <color>`) and re-rendered from its parts in canonical form. Asset paths (`fonts[].file`,
|
|
12
|
+
* `logo.*`) are relative to the plugin root (an optional leading `./`) and every segment is limited
|
|
13
|
+
* to `[A-Za-z0-9._-]`, so they need no escaping inside `url(...)`. Font families are limited to
|
|
14
|
+
* letters, digits, spaces and `-`. Free text (`name`, `description`, `logo.wordmark`) carries no
|
|
15
|
+
* control, format, line / paragraph separator or lone surrogate characters; it is text for the UI,
|
|
16
|
+
* never CSS. Whether the files exist and their size / signature / SVG rules are checked by
|
|
17
|
+
* the reader of the package, with {@link THEME_LIMITS}.
|
|
18
|
+
*
|
|
19
|
+
* The committed JSON Schema (`schemas/theme.v1.schema.json`) is generated from
|
|
20
|
+
* {@link ThemeFileSchema} (the shape only) by `pnpm gen:package-schemas`; token names, value
|
|
21
|
+
* grammar, path safety and readability are decided only by {@link parseThemeFile}.
|
|
22
|
+
*/
|
|
23
|
+
/** Limits of theme files and their assets. */
|
|
24
|
+
export declare const THEME_LIMITS: {
|
|
25
|
+
/** UTF-8 bytes of one theme file. */
|
|
26
|
+
readonly fileBytes: number;
|
|
27
|
+
/** Themes per plugin. */
|
|
28
|
+
readonly perPlugin: 10;
|
|
29
|
+
/** Total bytes of a plugin's theme assets (fonts and logos). */
|
|
30
|
+
readonly assetsBytes: number;
|
|
31
|
+
/** Fonts per theme. */
|
|
32
|
+
readonly fonts: 8;
|
|
33
|
+
/** Bytes of one woff2 font. */
|
|
34
|
+
readonly fontBytes: number;
|
|
35
|
+
/** Bytes of a logo SVG. */
|
|
36
|
+
readonly svgBytes: number;
|
|
37
|
+
/** Bytes of a logo PNG. */
|
|
38
|
+
readonly pngBytes: number;
|
|
39
|
+
/** Minimum pixel height of a logo PNG. */
|
|
40
|
+
readonly pngMinHeight: 64;
|
|
41
|
+
/** Characters of the wordmark. */
|
|
42
|
+
readonly wordmark: 24;
|
|
43
|
+
};
|
|
44
|
+
/** A theme of the plugin: a `./…/<id>.json` file ({@link ThemeFile}). */
|
|
45
|
+
export interface PluginThemeRef {
|
|
46
|
+
path: string;
|
|
47
|
+
}
|
|
48
|
+
/** One scheme's partial override; tokens left out keep the built-in value of that scheme. */
|
|
49
|
+
export interface ThemeSchemeOverride {
|
|
50
|
+
/** Overridable color tokens (`THEME_OVERRIDABLE.color`): `#RRGGBB` or `rgba(r,g,b,a)`. */
|
|
51
|
+
color?: Record<string, string>;
|
|
52
|
+
/** Shadow tokens: `<x> <y> <blur> [<spread>] <color>`. */
|
|
53
|
+
shadow?: Record<string, string>;
|
|
54
|
+
/** Pixels, integers 0-16. */
|
|
55
|
+
radius?: Partial<Record<"sm" | "md" | "bubble", number>>;
|
|
56
|
+
}
|
|
57
|
+
/** A woff2 font of the theme, put first in its role's font stack. */
|
|
58
|
+
export interface ThemeFont {
|
|
59
|
+
/** Letters, digits, spaces and `-`, ≤ 64 characters. */
|
|
60
|
+
family: string;
|
|
61
|
+
/** A `.woff2` path inside the plugin. */
|
|
62
|
+
file: string;
|
|
63
|
+
/** 100-900. */
|
|
64
|
+
weight: number;
|
|
65
|
+
style?: "normal" | "italic";
|
|
66
|
+
/** `prose` (`--cb-font-prose`) or `mono` (`--cb-font`, the UI's body font). */
|
|
67
|
+
role: "prose" | "mono";
|
|
68
|
+
}
|
|
69
|
+
/** The theme's logo; each part omitted keeps the built-in one. */
|
|
70
|
+
export interface ThemeLogo {
|
|
71
|
+
/** `.svg` or `.png` path inside the plugin. */
|
|
72
|
+
mark?: string;
|
|
73
|
+
/** Replaces `CAPYBARA`: ≤ 24 characters, no control or format characters. */
|
|
74
|
+
wordmark?: string;
|
|
75
|
+
/** `.svg` or `.png` path inside the plugin. */
|
|
76
|
+
favicon?: string;
|
|
77
|
+
}
|
|
78
|
+
/** `themes/<id>.json`. */
|
|
79
|
+
export interface ThemeFile {
|
|
80
|
+
name: LocalizedName;
|
|
81
|
+
description?: {
|
|
82
|
+
en: string;
|
|
83
|
+
zh?: string;
|
|
84
|
+
};
|
|
85
|
+
/** `dark`, `light` or both. */
|
|
86
|
+
schemes: Partial<Record<ThemeScheme, ThemeSchemeOverride>>;
|
|
87
|
+
fonts?: ThemeFont[];
|
|
88
|
+
logo?: ThemeLogo;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A theme file after {@link parseThemeFile}: values canonical. It holds only the file's own
|
|
92
|
+
* content (no built-in values), so it is what a catalog stores and compares: a change of the
|
|
93
|
+
* built-in tokens in core changes no stored theme. {@link mergeThemeSchemes} merges it onto the
|
|
94
|
+
* current built-in values where they are needed.
|
|
95
|
+
*/
|
|
96
|
+
export interface ParsedTheme extends ThemeFile {
|
|
97
|
+
id: string;
|
|
98
|
+
/** The only scheme of a single-scheme theme, else null. */
|
|
99
|
+
singleScheme: ThemeScheme | null;
|
|
100
|
+
}
|
|
101
|
+
/** Options of {@link parseThemeFile}. */
|
|
102
|
+
export interface ParseThemeOptions {
|
|
103
|
+
/**
|
|
104
|
+
* Check readability on the schemes merged onto the current built-in values (default true).
|
|
105
|
+
* False for a theme version already accepted into a catalog: its readability verdict was given
|
|
106
|
+
* when it was imported, so a later change of the built-in tokens does not block it. Grammar and
|
|
107
|
+
* token names are always checked.
|
|
108
|
+
*/
|
|
109
|
+
readability?: boolean;
|
|
110
|
+
}
|
|
111
|
+
/** `themes/night-city.json` → `night-city`. */
|
|
112
|
+
export declare function themeIdOf(path: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* The zod schema of a theme file's shape (strict objects). Token names and values are only
|
|
115
|
+
* strings here; see {@link parseThemeFile}. The JSON Schema is generated with
|
|
116
|
+
* `z.toJSONSchema(ThemeFileSchema, { io: "input" })`.
|
|
117
|
+
*/
|
|
118
|
+
export declare const ThemeFileSchema: z.ZodType<ThemeFile>;
|
|
119
|
+
/**
|
|
120
|
+
* The canonical form of a token value under the grammar of `group` (the one {@link parseThemeFile}
|
|
121
|
+
* applies), or undefined when `value` is not a string within it. For readers of stored themes that
|
|
122
|
+
* emit values again (the kernel's stylesheet, themes spec §8): a stored value is re-validated
|
|
123
|
+
* before it reaches CSS, so a changed database row cannot inject CSS.
|
|
124
|
+
*/
|
|
125
|
+
export declare function canonicalThemeValue(group: "color" | "shadow", value: unknown): string | undefined;
|
|
126
|
+
/** Whether `v` is a font family a theme may name: 1-64 letters, digits, spaces or `-`. */
|
|
127
|
+
export declare function isThemeFontFamily(v: unknown): v is string;
|
|
128
|
+
/**
|
|
129
|
+
* Whether `v` is an asset path a theme may name: plugin-root relative (an optional leading `./`),
|
|
130
|
+
* every segment of `[A-Za-z0-9._-]`, no `.` / `..` segments (the extension is not checked).
|
|
131
|
+
*/
|
|
132
|
+
export declare function isThemeAssetPath(v: unknown): v is string;
|
|
133
|
+
/**
|
|
134
|
+
* Each scheme the theme defines, merged onto the current built-in values (for swatches, the
|
|
135
|
+
* readability check and anything else that needs full values). A stored theme is read leniently:
|
|
136
|
+
* an override whose token name the built-in tokens no longer know (renamed in core), that is not
|
|
137
|
+
* overridable, or whose value falls outside the grammar is skipped, as the stylesheet skips it.
|
|
138
|
+
*/
|
|
139
|
+
export declare function mergeThemeSchemes(theme: Pick<ThemeFile, "schemes">): Partial<Record<ThemeScheme, MergedScheme>>;
|
|
140
|
+
/**
|
|
141
|
+
* Parses and validates a theme file: the parsed JSON value or the file text (larger than
|
|
142
|
+
* {@link THEME_LIMITS}`.fileBytes`, measured as text or as the value's JSON, is refused). Checks the id, the shape, token names against
|
|
143
|
+
* the generated allowlist (an unknown or non-overridable name is an error), the value grammar,
|
|
144
|
+
* fonts and logo; then (unless `options.readability` is false) merges every defined scheme onto
|
|
145
|
+
* the built-in tokens ({@link mergeThemeSchemes}) and reports each readability issue as an error
|
|
146
|
+
* starting `unreadable:`. Returned values are canonical (uppercase
|
|
147
|
+
* hex, rgba and shadows re-rendered from their parts). Invalid input returns `{ errors }`
|
|
148
|
+
* (`<path>: <reason>`, English, at most 50); never throws.
|
|
149
|
+
*/
|
|
150
|
+
export declare function parseThemeFile(id: string, json: unknown, options?: ParseThemeOptions): ParsedTheme | {
|
|
151
|
+
errors: string[];
|
|
152
|
+
};
|