@typecaast/skins 0.1.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/dist/index.js ADDED
@@ -0,0 +1,2673 @@
1
+ import { z } from 'zod';
2
+ import { defineSkin, MessageContent, fadeSlideIn, popIn, TypingDots } from '@typecaast/skin-kit';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ // src/slack/index.ts
6
+
7
+ // src/slack/tokens.ts
8
+ var SLACK_COLORS = {
9
+ light: {
10
+ bg: "#ffffff",
11
+ text: "#1d1c1d",
12
+ subtle: "#616061",
13
+ border: "#e2e2e2",
14
+ headerBg: "#ffffff",
15
+ link: "#1264a3",
16
+ mentionText: "#1264a3",
17
+ mentionBg: "#e8f5fa",
18
+ codeText: "#e01e5a",
19
+ codeBg: "#f6f6f6",
20
+ codeBorder: "#e2e2e2",
21
+ reactionBg: "#f8f8f8",
22
+ reactionBorder: "#e2e2e2",
23
+ reactionText: "#454245",
24
+ composerBg: "#ffffff",
25
+ composerBorder: "#8d8d8d",
26
+ placeholder: "#8d8d8d",
27
+ primary: "#007a5a",
28
+ primaryText: "#ffffff",
29
+ buttonBorder: "#d1d1d1",
30
+ buttonText: "#1d1c1d",
31
+ appBadgeBg: "#e8e8e8",
32
+ appBadgeText: "#616061",
33
+ cardBar: "#dddddd",
34
+ caret: "#1264a3"
35
+ },
36
+ dark: {
37
+ bg: "#1a1d21",
38
+ text: "#d1d2d3",
39
+ subtle: "#ababad",
40
+ border: "#35373b",
41
+ headerBg: "#1a1d21",
42
+ link: "#1d9bd1",
43
+ mentionText: "#1d9bd1",
44
+ mentionBg: "rgba(29,155,209,0.12)",
45
+ codeText: "#e06c9a",
46
+ codeBg: "#222529",
47
+ codeBorder: "#35373b",
48
+ reactionBg: "#222529",
49
+ reactionBorder: "#35373b",
50
+ reactionText: "#d1d2d3",
51
+ composerBg: "#222529",
52
+ composerBorder: "#565856",
53
+ placeholder: "#9a9b9d",
54
+ primary: "#007a5a",
55
+ primaryText: "#ffffff",
56
+ buttonBorder: "#565856",
57
+ buttonText: "#d1d2d3",
58
+ appBadgeBg: "#35373b",
59
+ appBadgeText: "#ababad",
60
+ cardBar: "#35373b",
61
+ caret: "#1d9bd1"
62
+ }
63
+ };
64
+ var slackTokens = {
65
+ light: { colors: SLACK_COLORS.light },
66
+ dark: { colors: SLACK_COLORS.dark }
67
+ };
68
+
69
+ // src/slack/fonts.ts
70
+ var slackFonts = [
71
+ {
72
+ family: "Lato",
73
+ weights: [400, 700, 900],
74
+ sources: [
75
+ {
76
+ url: "https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2",
77
+ weight: 400,
78
+ format: "woff2"
79
+ },
80
+ {
81
+ url: "https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2",
82
+ weight: 700,
83
+ format: "woff2"
84
+ },
85
+ {
86
+ url: "https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2",
87
+ weight: 900,
88
+ format: "woff2"
89
+ }
90
+ ]
91
+ }
92
+ ];
93
+ var SLACK_FONT_STACK = 'Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
94
+ var AVATAR_RADIUS = 8;
95
+ function formatTime(atMs) {
96
+ const base = 9 * 3600 * 1e3;
97
+ const total = Math.floor((base + atMs) / 1e3);
98
+ const h = Math.floor(total / 3600) % 24;
99
+ const m = Math.floor(total % 3600 / 60);
100
+ const ampm = h >= 12 ? "PM" : "AM";
101
+ const hr = h % 12 === 0 ? 12 : h % 12;
102
+ return `${hr}:${String(m).padStart(2, "0")} ${ampm}`;
103
+ }
104
+ function initials(name) {
105
+ return name.split(/\s+/).map((w) => w.charAt(0)).slice(0, 2).join("").toUpperCase();
106
+ }
107
+ function markStyles(c) {
108
+ return {
109
+ link: { color: c.link, textDecoration: "none" },
110
+ mention: {
111
+ color: c.mentionText,
112
+ background: c.mentionBg,
113
+ borderRadius: 3,
114
+ padding: "0 2px",
115
+ fontWeight: 600
116
+ },
117
+ code: {
118
+ color: c.codeText,
119
+ background: c.codeBg,
120
+ border: `1px solid ${c.codeBorder}`,
121
+ borderRadius: 3,
122
+ padding: "1px 4px",
123
+ fontFamily: "Menlo, Monaco, Consolas, monospace",
124
+ fontSize: "0.85em"
125
+ }
126
+ };
127
+ }
128
+ var Avatar = ({ theme, participant, size = 36 }) => {
129
+ const c = SLACK_COLORS[theme];
130
+ if (participant.avatar) {
131
+ return /* @__PURE__ */ jsx(
132
+ "img",
133
+ {
134
+ src: participant.avatar,
135
+ alt: participant.name,
136
+ width: size,
137
+ height: size,
138
+ style: {
139
+ width: size,
140
+ height: size,
141
+ borderRadius: AVATAR_RADIUS,
142
+ objectFit: "cover",
143
+ display: "block"
144
+ }
145
+ }
146
+ );
147
+ }
148
+ return /* @__PURE__ */ jsx(
149
+ "div",
150
+ {
151
+ "aria-label": participant.name,
152
+ style: {
153
+ width: size,
154
+ height: size,
155
+ borderRadius: AVATAR_RADIUS,
156
+ background: participant.color ?? "#4a154b",
157
+ color: "#ffffff",
158
+ display: "flex",
159
+ alignItems: "center",
160
+ justifyContent: "center",
161
+ fontWeight: 700,
162
+ fontSize: size * 0.4,
163
+ border: theme === "dark" ? `1px solid ${c.border}` : void 0
164
+ },
165
+ children: initials(participant.name)
166
+ }
167
+ );
168
+ };
169
+ var Reaction = ({ theme, reaction }) => {
170
+ const c = SLACK_COLORS[theme];
171
+ return /* @__PURE__ */ jsxs(
172
+ "span",
173
+ {
174
+ style: {
175
+ ...popIn(reaction.progress),
176
+ display: "inline-flex",
177
+ alignItems: "center",
178
+ gap: 4,
179
+ background: c.reactionBg,
180
+ border: `1px solid ${c.reactionBorder}`,
181
+ color: c.reactionText,
182
+ borderRadius: 12,
183
+ padding: "1px 7px",
184
+ height: 22,
185
+ fontSize: 12
186
+ },
187
+ children: [
188
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: reaction.emoji }),
189
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontVariantNumeric: "tabular-nums" }, children: reaction.count })
190
+ ]
191
+ }
192
+ );
193
+ };
194
+ var TypingIndicator = ({ theme, typing, author }) => {
195
+ const c = SLACK_COLORS[theme];
196
+ return /* @__PURE__ */ jsxs(
197
+ "div",
198
+ {
199
+ style: {
200
+ display: "flex",
201
+ alignItems: "center",
202
+ gap: 6,
203
+ padding: "2px 16px 4px 60px",
204
+ color: c.subtle,
205
+ fontSize: 12
206
+ },
207
+ children: [
208
+ /* @__PURE__ */ jsx(TypingDots, { progress: typing.progress, color: c.subtle, size: 5 }),
209
+ /* @__PURE__ */ jsxs("span", { children: [
210
+ author.name,
211
+ " is typing\u2026"
212
+ ] })
213
+ ]
214
+ }
215
+ );
216
+ };
217
+ var Caret = ({ color }) => /* @__PURE__ */ jsx(
218
+ "span",
219
+ {
220
+ style: {
221
+ display: "inline-block",
222
+ width: 1.5,
223
+ height: "1.05em",
224
+ background: color,
225
+ marginLeft: 1,
226
+ verticalAlign: "text-bottom"
227
+ }
228
+ }
229
+ );
230
+ var Composer = ({ theme, composer }) => {
231
+ const c = SLACK_COLORS[theme];
232
+ const hasText = composer.text.length > 0;
233
+ return /* @__PURE__ */ jsx("div", { style: { flex: "0 0 auto", padding: "4px 16px 14px" }, children: /* @__PURE__ */ jsx(
234
+ "div",
235
+ {
236
+ style: {
237
+ border: `1px solid ${c.composerBorder}`,
238
+ borderRadius: 8,
239
+ background: c.composerBg,
240
+ padding: "9px 12px",
241
+ minHeight: 22,
242
+ fontSize: 15,
243
+ color: c.text
244
+ },
245
+ children: hasText ? /* @__PURE__ */ jsxs("span", { children: [
246
+ composer.text,
247
+ /* @__PURE__ */ jsx(Caret, { color: c.caret })
248
+ ] }) : /* @__PURE__ */ jsx("span", { style: { color: c.placeholder }, children: "Reply\u2026" })
249
+ }
250
+ ) });
251
+ };
252
+ function buttonStyle(c, primary) {
253
+ const base = {
254
+ borderRadius: 4,
255
+ padding: "7px 12px",
256
+ fontWeight: 700,
257
+ fontSize: 13,
258
+ cursor: "default",
259
+ fontFamily: "inherit",
260
+ lineHeight: 1
261
+ };
262
+ return primary ? { ...base, background: c.primary, color: c.primaryText, border: "none" } : {
263
+ ...base,
264
+ background: "transparent",
265
+ color: c.buttonText,
266
+ border: `1px solid ${c.buttonBorder}`
267
+ };
268
+ }
269
+ var SystemMessage = ({ theme, message, author }) => {
270
+ const c = SLACK_COLORS[theme];
271
+ const actions = message.system?.actions ?? [];
272
+ return /* @__PURE__ */ jsxs(
273
+ "div",
274
+ {
275
+ style: {
276
+ display: "flex",
277
+ gap: 8,
278
+ padding: "8px 16px 2px",
279
+ ...fadeSlideIn(message.revealProgress)
280
+ },
281
+ children: [
282
+ /* @__PURE__ */ jsx("div", { style: { flex: "0 0 36px", width: 36 }, children: author ? /* @__PURE__ */ jsx(Avatar, { theme, participant: author, size: 36 }) : null }),
283
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
284
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
285
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 700, color: c.text }, children: author?.name ?? "App" }),
286
+ /* @__PURE__ */ jsx(
287
+ "span",
288
+ {
289
+ style: {
290
+ fontSize: 10,
291
+ fontWeight: 700,
292
+ letterSpacing: 0.4,
293
+ background: c.appBadgeBg,
294
+ color: c.appBadgeText,
295
+ borderRadius: 2,
296
+ padding: "1px 4px"
297
+ },
298
+ children: "APP"
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: c.subtle }, children: formatTime(message.atMs) })
302
+ ] }),
303
+ /* @__PURE__ */ jsxs(
304
+ "div",
305
+ {
306
+ style: {
307
+ marginTop: 4,
308
+ borderLeft: `4px solid ${c.cardBar}`,
309
+ borderRadius: 2,
310
+ paddingLeft: 12
311
+ },
312
+ children: [
313
+ /* @__PURE__ */ jsx("div", { style: { color: c.text }, children: /* @__PURE__ */ jsx(MessageContent, { nodes: message.content, styles: markStyles(c) }) }),
314
+ actions.length > 0 ? /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 8, marginTop: 8 }, children: actions.map((a, i) => /* @__PURE__ */ jsx("button", { type: "button", style: buttonStyle(c, i === 0), children: a.label }, i)) }) : null
315
+ ]
316
+ }
317
+ )
318
+ ] })
319
+ ]
320
+ }
321
+ );
322
+ };
323
+ var Message = ({ theme, message, author }) => {
324
+ const c = SLACK_COLORS[theme];
325
+ const grouped = message.isGrouped;
326
+ return /* @__PURE__ */ jsxs(
327
+ "div",
328
+ {
329
+ style: {
330
+ display: "flex",
331
+ gap: 8,
332
+ padding: grouped ? "2px 16px" : "8px 16px 2px",
333
+ ...fadeSlideIn(message.revealProgress)
334
+ },
335
+ children: [
336
+ /* @__PURE__ */ jsx("div", { style: { flex: "0 0 36px", width: 36 }, children: grouped ? null : /* @__PURE__ */ jsx(Avatar, { theme, participant: author, size: 36 }) }),
337
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
338
+ grouped ? null : /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 8 }, children: [
339
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 700, color: c.text }, children: author.name }),
340
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: c.subtle }, children: formatTime(message.atMs) })
341
+ ] }),
342
+ /* @__PURE__ */ jsx("div", { style: { color: c.text, wordBreak: "break-word" }, children: /* @__PURE__ */ jsx(
343
+ MessageContent,
344
+ {
345
+ nodes: message.content,
346
+ styles: markStyles(c),
347
+ imageStyle: {
348
+ borderRadius: 8,
349
+ marginTop: 4,
350
+ border: `1px solid ${c.border}`,
351
+ maxWidth: 360
352
+ }
353
+ }
354
+ ) }),
355
+ message.reactions.length > 0 ? /* @__PURE__ */ jsx(
356
+ "div",
357
+ {
358
+ style: {
359
+ display: "flex",
360
+ gap: 4,
361
+ marginTop: 4,
362
+ flexWrap: "wrap"
363
+ },
364
+ children: message.reactions.map((r, i) => /* @__PURE__ */ jsx(Reaction, { theme, reaction: r }, i))
365
+ }
366
+ ) : null
367
+ ] })
368
+ ]
369
+ }
370
+ );
371
+ };
372
+ var Frame = ({
373
+ theme,
374
+ options,
375
+ children
376
+ }) => {
377
+ const c = SLACK_COLORS[theme];
378
+ const channel = typeof options?.channel === "string" ? options.channel : "#general";
379
+ return /* @__PURE__ */ jsxs(
380
+ "div",
381
+ {
382
+ style: {
383
+ fontFamily: SLACK_FONT_STACK,
384
+ background: c.bg,
385
+ color: c.text,
386
+ display: "flex",
387
+ flexDirection: "column",
388
+ height: "100%",
389
+ width: "100%",
390
+ fontSize: 15,
391
+ lineHeight: 1.46668,
392
+ WebkitFontSmoothing: "antialiased"
393
+ },
394
+ children: [
395
+ /* @__PURE__ */ jsxs(
396
+ "header",
397
+ {
398
+ style: {
399
+ flex: "0 0 auto",
400
+ padding: "10px 16px",
401
+ borderBottom: `1px solid ${c.border}`,
402
+ display: "flex",
403
+ alignItems: "baseline",
404
+ gap: 8
405
+ },
406
+ children: [
407
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 900, fontSize: 18, color: c.text }, children: "Thread" }),
408
+ /* @__PURE__ */ jsx("span", { style: { color: c.subtle, fontSize: 13 }, children: channel })
409
+ ]
410
+ }
411
+ ),
412
+ /* @__PURE__ */ jsx(
413
+ "div",
414
+ {
415
+ style: {
416
+ flex: "1 1 auto",
417
+ minHeight: 0,
418
+ display: "flex",
419
+ flexDirection: "column"
420
+ },
421
+ children
422
+ }
423
+ )
424
+ ]
425
+ }
426
+ );
427
+ };
428
+ var slackComponents = {
429
+ Frame,
430
+ Message,
431
+ TypingIndicator,
432
+ Reaction,
433
+ Composer,
434
+ SystemMessage,
435
+ Avatar
436
+ };
437
+
438
+ // src/slack/capabilities.ts
439
+ var slackCapabilities = {
440
+ events: {
441
+ message: "native",
442
+ reaction: "native",
443
+ typing: "native",
444
+ // "X is typing…"
445
+ composerType: "native",
446
+ send: "native",
447
+ edit: "native",
448
+ delete: "native",
449
+ readReceipt: "unsupported",
450
+ // Slack has no per-message read receipts in threads
451
+ system: "native",
452
+ // app/PR cards
453
+ beat: "native"
454
+ },
455
+ content: {
456
+ text: true,
457
+ image: true
458
+ },
459
+ reactions: true,
460
+ threads: true,
461
+ readReceipts: false
462
+ };
463
+
464
+ // src/slack/index.ts
465
+ var slackOptionsSchema = z.object({
466
+ /** Channel label shown in the thread header (e.g. `"#alerts"`). */
467
+ channel: z.string().optional(),
468
+ showThreadHeader: z.boolean().optional()
469
+ });
470
+ var slack = defineSkin({
471
+ id: "slack",
472
+ meta: {
473
+ name: "Slack",
474
+ defaultCanvas: { width: 880, height: 720 },
475
+ supportsThemes: ["light", "dark"],
476
+ capabilities: slackCapabilities,
477
+ optionsSchema: slackOptionsSchema,
478
+ fonts: slackFonts
479
+ },
480
+ components: slackComponents,
481
+ tokens: slackTokens
482
+ });
483
+
484
+ // src/claude-code/tokens.ts
485
+ var TUI_COLORS = {
486
+ bg: "#1a1a1a",
487
+ titleBar: "#2a2a2a",
488
+ border: "#3a3a3a",
489
+ text: "#e6e6e6",
490
+ dim: "#8b8b8b",
491
+ prompt: "#d97757",
492
+ // Claude coral
493
+ accent: "#d97757",
494
+ spinner: "#d97757",
495
+ system: "#7aa2f7",
496
+ // tool/blue
497
+ cursor: "#d97757",
498
+ dotRed: "#ff5f56",
499
+ dotYellow: "#ffbd2e",
500
+ dotGreen: "#27c93f"
501
+ };
502
+ var MONO_STACK = '"JetBrains Mono", "SF Mono", Menlo, Monaco, "Cascadia Code", "Roboto Mono", monospace';
503
+ function flatten(content) {
504
+ return content.map((node) => {
505
+ if (node.type === "text") {
506
+ const spans = node.spans;
507
+ return spans.map(
508
+ (s) => typeof s.value === "string" ? s.value : typeof s.label === "string" ? s.label : typeof s.href === "string" ? s.href : ""
509
+ ).join("");
510
+ }
511
+ if (node.type === "image") {
512
+ const alt = node.alt;
513
+ return `[image${alt ? `: ${alt}` : ""}]`;
514
+ }
515
+ return "";
516
+ }).join(" ");
517
+ }
518
+ function streamed(text, progress) {
519
+ if (progress >= 1) return text;
520
+ return text.slice(0, Math.round(progress * text.length));
521
+ }
522
+ var lineStyle = {
523
+ padding: "2px 0",
524
+ whiteSpace: "pre-wrap",
525
+ wordBreak: "break-word"
526
+ };
527
+ var Avatar2 = () => null;
528
+ var Reaction2 = ({ reaction }) => /* @__PURE__ */ jsxs("span", { style: { color: TUI_COLORS.dim }, children: [
529
+ " ",
530
+ reaction.emoji
531
+ ] });
532
+ var SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
533
+ var TypingIndicator2 = ({ typing }) => {
534
+ const frame = Math.floor(typing.progress * SPINNER.length * 6) % SPINNER.length;
535
+ return /* @__PURE__ */ jsxs("div", { style: { ...lineStyle, color: TUI_COLORS.dim }, children: [
536
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.spinner }, children: SPINNER[frame] }),
537
+ " Thinking\u2026"
538
+ ] });
539
+ };
540
+ var Message2 = ({ message }) => {
541
+ const text = streamed(flatten(message.content), message.revealProgress);
542
+ if (message.isSelf) {
543
+ return /* @__PURE__ */ jsxs("div", { style: { ...lineStyle, display: "flex", gap: 8 }, children: [
544
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.prompt }, children: "\u276F" }),
545
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.text }, children: text })
546
+ ] });
547
+ }
548
+ return /* @__PURE__ */ jsxs("div", { style: { ...lineStyle, display: "flex", gap: 8 }, children: [
549
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.accent }, children: "\u23FA" }),
550
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.text }, children: text })
551
+ ] });
552
+ };
553
+ var SystemMessage2 = ({ message }) => {
554
+ const text = streamed(flatten(message.content), message.revealProgress);
555
+ return /* @__PURE__ */ jsxs("div", { style: { ...lineStyle, display: "flex", gap: 8, color: TUI_COLORS.dim }, children: [
556
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.system }, children: "\u23BF" }),
557
+ /* @__PURE__ */ jsx("span", { children: text })
558
+ ] });
559
+ };
560
+ var Composer2 = ({ composer }) => /* @__PURE__ */ jsxs(
561
+ "div",
562
+ {
563
+ style: {
564
+ display: "flex",
565
+ gap: 8,
566
+ padding: "6px 0 2px",
567
+ marginTop: 6,
568
+ borderTop: `1px solid ${TUI_COLORS.border}`
569
+ },
570
+ children: [
571
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.prompt }, children: "\u276F" }),
572
+ /* @__PURE__ */ jsxs("span", { style: { whiteSpace: "pre-wrap", color: TUI_COLORS.text }, children: [
573
+ composer.text,
574
+ /* @__PURE__ */ jsx("span", { style: { color: TUI_COLORS.cursor }, children: "\u2588" })
575
+ ] })
576
+ ]
577
+ }
578
+ );
579
+ var Dot = ({ color }) => /* @__PURE__ */ jsx(
580
+ "span",
581
+ {
582
+ style: {
583
+ width: 11,
584
+ height: 11,
585
+ borderRadius: "50%",
586
+ background: color,
587
+ display: "inline-block"
588
+ }
589
+ }
590
+ );
591
+ var Frame2 = ({
592
+ options,
593
+ children
594
+ }) => {
595
+ const title = typeof options?.title === "string" ? options.title : "claude \u2014 typecaast";
596
+ return /* @__PURE__ */ jsxs(
597
+ "div",
598
+ {
599
+ style: {
600
+ fontFamily: MONO_STACK,
601
+ background: TUI_COLORS.bg,
602
+ color: TUI_COLORS.text,
603
+ display: "flex",
604
+ flexDirection: "column",
605
+ height: "100%",
606
+ width: "100%",
607
+ fontSize: 13,
608
+ lineHeight: 1.5,
609
+ WebkitFontSmoothing: "antialiased"
610
+ },
611
+ children: [
612
+ /* @__PURE__ */ jsxs(
613
+ "div",
614
+ {
615
+ style: {
616
+ flex: "0 0 auto",
617
+ height: 30,
618
+ background: TUI_COLORS.titleBar,
619
+ display: "flex",
620
+ alignItems: "center",
621
+ gap: 8,
622
+ padding: "0 12px",
623
+ borderBottom: `1px solid ${TUI_COLORS.border}`
624
+ },
625
+ children: [
626
+ /* @__PURE__ */ jsx(Dot, { color: TUI_COLORS.dotRed }),
627
+ /* @__PURE__ */ jsx(Dot, { color: TUI_COLORS.dotYellow }),
628
+ /* @__PURE__ */ jsx(Dot, { color: TUI_COLORS.dotGreen }),
629
+ /* @__PURE__ */ jsx("span", { style: { marginLeft: 6, color: TUI_COLORS.dim, fontSize: 12 }, children: title })
630
+ ]
631
+ }
632
+ ),
633
+ /* @__PURE__ */ jsx(
634
+ "div",
635
+ {
636
+ style: {
637
+ flex: "1 1 auto",
638
+ minHeight: 0,
639
+ display: "flex",
640
+ flexDirection: "column",
641
+ padding: "10px 14px",
642
+ overflow: "hidden"
643
+ },
644
+ children
645
+ }
646
+ )
647
+ ]
648
+ }
649
+ );
650
+ };
651
+ var tuiComponents = {
652
+ Frame: Frame2,
653
+ Message: Message2,
654
+ TypingIndicator: TypingIndicator2,
655
+ Reaction: Reaction2,
656
+ Composer: Composer2,
657
+ SystemMessage: SystemMessage2,
658
+ Avatar: Avatar2
659
+ };
660
+
661
+ // src/claude-code/capabilities.ts
662
+ var tuiCapabilities = {
663
+ events: {
664
+ message: "native",
665
+ composerType: "native",
666
+ send: "native",
667
+ typing: "native",
668
+ // spinner
669
+ system: "native",
670
+ // tool/output lines
671
+ reaction: "unsupported",
672
+ readReceipt: "unsupported",
673
+ edit: "native",
674
+ delete: "native",
675
+ beat: "native"
676
+ },
677
+ content: {
678
+ text: true,
679
+ image: false
680
+ // terminals don't render images
681
+ },
682
+ reactions: false,
683
+ threads: false,
684
+ readReceipts: false
685
+ };
686
+
687
+ // src/claude-code/fonts.ts
688
+ var tuiFonts = [
689
+ {
690
+ family: "JetBrains Mono",
691
+ weights: [400, 700],
692
+ sources: [
693
+ {
694
+ url: "https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono@latest/latin-400-normal.woff2",
695
+ weight: 400,
696
+ format: "woff2"
697
+ },
698
+ {
699
+ url: "https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono@latest/latin-700-normal.woff2",
700
+ weight: 700,
701
+ format: "woff2"
702
+ }
703
+ ]
704
+ }
705
+ ];
706
+
707
+ // src/claude-code/index.ts
708
+ var tuiOptionsSchema = z.object({
709
+ /** Title-bar label (e.g. `"claude — zsh"`). */
710
+ title: z.string().optional()
711
+ });
712
+ var claudeCode = defineSkin({
713
+ id: "claude-code",
714
+ meta: {
715
+ name: "Claude Code (TUI)",
716
+ defaultCanvas: { width: 720, height: 480 },
717
+ supportsThemes: ["dark"],
718
+ capabilities: tuiCapabilities,
719
+ optionsSchema: tuiOptionsSchema,
720
+ fonts: tuiFonts
721
+ },
722
+ components: tuiComponents
723
+ });
724
+
725
+ // src/imessage/tokens.ts
726
+ var IMESSAGE_COLORS = {
727
+ light: {
728
+ bg: "#ffffff",
729
+ text: "#000000",
730
+ subtle: "#8e8e93",
731
+ selfBubble: "#0b93f6",
732
+ selfText: "#ffffff",
733
+ otherBubble: "#e9e9eb",
734
+ otherText: "#000000",
735
+ navBg: "rgba(249,249,249,0.94)",
736
+ navBorder: "rgba(0,0,0,0.12)",
737
+ statusText: "#000000",
738
+ composerBg: "#ffffff",
739
+ composerBorder: "#d1d1d6",
740
+ placeholder: "#8e8e93",
741
+ keyboardBg: "#d1d4db",
742
+ keyBg: "#ffffff",
743
+ keyText: "#000000",
744
+ keyShadow: "rgba(0,0,0,0.28)",
745
+ tapbackBg: "#e9e9eb",
746
+ link: "#0b93f6"
747
+ },
748
+ dark: {
749
+ bg: "#000000",
750
+ text: "#ffffff",
751
+ subtle: "#8e8e93",
752
+ selfBubble: "#0b93f6",
753
+ selfText: "#ffffff",
754
+ otherBubble: "#26252a",
755
+ otherText: "#ffffff",
756
+ navBg: "rgba(22,22,22,0.92)",
757
+ navBorder: "rgba(255,255,255,0.12)",
758
+ statusText: "#ffffff",
759
+ composerBg: "#1c1c1e",
760
+ composerBorder: "#38383a",
761
+ placeholder: "#8e8e93",
762
+ keyboardBg: "#1c1c1e",
763
+ keyBg: "#6b6b6f",
764
+ keyText: "#ffffff",
765
+ keyShadow: "rgba(0,0,0,0.5)",
766
+ tapbackBg: "#26252a",
767
+ link: "#0b93f6"
768
+ }
769
+ };
770
+ var IMESSAGE_FONT_STACK = 'Inter, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif';
771
+ var imessageTokens = {
772
+ light: {
773
+ colors: IMESSAGE_COLORS.light
774
+ },
775
+ dark: { colors: IMESSAGE_COLORS.dark }
776
+ };
777
+ var RADIUS = 18;
778
+ var TAIL = 5;
779
+ function initials2(name) {
780
+ return name.split(/\s+/).map((w) => w.charAt(0)).slice(0, 2).join("").toUpperCase();
781
+ }
782
+ function markStyles2(c) {
783
+ return {
784
+ link: { color: c.link, textDecoration: "underline" },
785
+ code: {
786
+ fontFamily: "Menlo, monospace",
787
+ fontSize: "0.9em"
788
+ }
789
+ };
790
+ }
791
+ var StatusBar = ({ theme }) => {
792
+ const c = IMESSAGE_COLORS[theme];
793
+ return /* @__PURE__ */ jsxs(
794
+ "div",
795
+ {
796
+ style: {
797
+ flex: "0 0 auto",
798
+ height: 44,
799
+ display: "flex",
800
+ alignItems: "center",
801
+ justifyContent: "space-between",
802
+ padding: "0 24px",
803
+ color: c.statusText,
804
+ fontWeight: 600,
805
+ fontSize: 15
806
+ },
807
+ children: [
808
+ /* @__PURE__ */ jsx("span", { children: "9:41" }),
809
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
810
+ /* @__PURE__ */ jsx(
811
+ "span",
812
+ {
813
+ style: { display: "inline-flex", alignItems: "flex-end", gap: 1.5 },
814
+ children: [5, 7, 9, 11].map((h, i) => /* @__PURE__ */ jsx(
815
+ "span",
816
+ {
817
+ style: {
818
+ width: 3,
819
+ height: h,
820
+ borderRadius: 1,
821
+ background: c.statusText
822
+ }
823
+ },
824
+ i
825
+ ))
826
+ }
827
+ ),
828
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600 }, children: "5G" }),
829
+ /* @__PURE__ */ jsx(
830
+ "span",
831
+ {
832
+ style: {
833
+ display: "inline-block",
834
+ width: 24,
835
+ height: 12,
836
+ borderRadius: 3,
837
+ border: `1px solid ${c.statusText}`,
838
+ position: "relative",
839
+ opacity: 0.9
840
+ },
841
+ children: /* @__PURE__ */ jsx(
842
+ "span",
843
+ {
844
+ style: {
845
+ position: "absolute",
846
+ inset: 1.5,
847
+ width: "70%",
848
+ borderRadius: 1,
849
+ background: c.statusText
850
+ }
851
+ }
852
+ )
853
+ }
854
+ )
855
+ ] })
856
+ ]
857
+ }
858
+ );
859
+ };
860
+ var Avatar3 = ({ participant, size = 30 }) => {
861
+ if (participant.avatar) {
862
+ return /* @__PURE__ */ jsx(
863
+ "img",
864
+ {
865
+ src: participant.avatar,
866
+ alt: participant.name,
867
+ width: size,
868
+ height: size,
869
+ style: {
870
+ width: size,
871
+ height: size,
872
+ borderRadius: "50%",
873
+ objectFit: "cover"
874
+ }
875
+ }
876
+ );
877
+ }
878
+ return /* @__PURE__ */ jsx(
879
+ "div",
880
+ {
881
+ style: {
882
+ width: size,
883
+ height: size,
884
+ borderRadius: "50%",
885
+ background: participant.color ?? "#a9a9af",
886
+ color: "#fff",
887
+ display: "flex",
888
+ alignItems: "center",
889
+ justifyContent: "center",
890
+ fontSize: size * 0.4,
891
+ fontWeight: 500
892
+ },
893
+ children: initials2(participant.name)
894
+ }
895
+ );
896
+ };
897
+ var NavBar = ({ theme, title, participant }) => {
898
+ const c = IMESSAGE_COLORS[theme];
899
+ return /* @__PURE__ */ jsxs(
900
+ "div",
901
+ {
902
+ style: {
903
+ flex: "0 0 auto",
904
+ display: "flex",
905
+ flexDirection: "column",
906
+ alignItems: "center",
907
+ gap: 3,
908
+ padding: "4px 0 8px",
909
+ background: c.navBg,
910
+ borderBottom: `0.5px solid ${c.navBorder}`,
911
+ backdropFilter: "blur(20px)"
912
+ },
913
+ children: [
914
+ participant ? /* @__PURE__ */ jsx(Avatar3, { theme, participant, size: 42 }) : null,
915
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, fontWeight: 500, color: c.text }, children: [
916
+ title,
917
+ /* @__PURE__ */ jsx("span", { style: { marginLeft: 3, color: c.subtle }, children: "\u203A" })
918
+ ] })
919
+ ]
920
+ }
921
+ );
922
+ };
923
+ var Reaction3 = ({ theme, reaction }) => {
924
+ const c = IMESSAGE_COLORS[theme];
925
+ return /* @__PURE__ */ jsx(
926
+ "span",
927
+ {
928
+ style: {
929
+ ...popIn(reaction.progress),
930
+ display: "inline-flex",
931
+ alignItems: "center",
932
+ justifyContent: "center",
933
+ background: c.tapbackBg,
934
+ borderRadius: 12,
935
+ padding: "2px 6px",
936
+ fontSize: 12,
937
+ boxShadow: `0 1px 2px ${theme === "dark" ? "rgba(0,0,0,0.5)" : "rgba(0,0,0,0.15)"}`
938
+ },
939
+ children: reaction.emoji
940
+ }
941
+ );
942
+ };
943
+ var Message3 = ({ theme, message }) => {
944
+ const c = IMESSAGE_COLORS[theme];
945
+ const self = message.isSelf;
946
+ const bubbleStyle = {
947
+ maxWidth: "72%",
948
+ padding: "7px 12px",
949
+ borderRadius: RADIUS,
950
+ background: self ? c.selfBubble : c.otherBubble,
951
+ color: self ? c.selfText : c.otherText,
952
+ fontSize: 16,
953
+ lineHeight: 1.3,
954
+ wordBreak: "break-word",
955
+ ...self ? { borderBottomRightRadius: TAIL } : { borderBottomLeftRadius: TAIL }
956
+ };
957
+ return /* @__PURE__ */ jsx(
958
+ "div",
959
+ {
960
+ style: {
961
+ display: "flex",
962
+ justifyContent: self ? "flex-end" : "flex-start",
963
+ padding: message.isGrouped ? "1px 12px" : "3px 12px",
964
+ ...fadeSlideIn(message.revealProgress, { distance: 6 })
965
+ },
966
+ children: /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
967
+ /* @__PURE__ */ jsx("div", { style: bubbleStyle, children: /* @__PURE__ */ jsx(
968
+ MessageContent,
969
+ {
970
+ nodes: message.content,
971
+ styles: markStyles2(c),
972
+ imageStyle: { borderRadius: 14, maxWidth: 240, marginTop: 2 }
973
+ }
974
+ ) }),
975
+ message.reactions.length > 0 ? /* @__PURE__ */ jsx(
976
+ "div",
977
+ {
978
+ style: {
979
+ position: "absolute",
980
+ top: -14,
981
+ ...self ? { left: -6 } : { right: -6 },
982
+ display: "flex",
983
+ gap: 2
984
+ },
985
+ children: message.reactions.map((r, i) => /* @__PURE__ */ jsx(Reaction3, { theme, reaction: r }, i))
986
+ }
987
+ ) : null
988
+ ] })
989
+ }
990
+ );
991
+ };
992
+ var TypingIndicator3 = ({ theme, typing }) => {
993
+ const c = IMESSAGE_COLORS[theme];
994
+ return /* @__PURE__ */ jsx(
995
+ "div",
996
+ {
997
+ style: {
998
+ display: "flex",
999
+ justifyContent: "flex-start",
1000
+ padding: "3px 12px"
1001
+ },
1002
+ children: /* @__PURE__ */ jsx(
1003
+ "div",
1004
+ {
1005
+ style: {
1006
+ background: c.otherBubble,
1007
+ borderRadius: RADIUS,
1008
+ borderBottomLeftRadius: TAIL,
1009
+ padding: "10px 14px"
1010
+ },
1011
+ children: /* @__PURE__ */ jsx(
1012
+ TypingDots,
1013
+ {
1014
+ progress: typing.progress,
1015
+ color: c.subtle,
1016
+ size: 8,
1017
+ gap: 5
1018
+ }
1019
+ )
1020
+ }
1021
+ )
1022
+ }
1023
+ );
1024
+ };
1025
+ var SystemMessage3 = ({ theme, message }) => {
1026
+ const c = IMESSAGE_COLORS[theme];
1027
+ const text = message.content.map(
1028
+ (n) => n.type === "text" ? n.spans.map((s) => s.value ?? "").join("") : ""
1029
+ ).join(" ");
1030
+ return /* @__PURE__ */ jsx(
1031
+ "div",
1032
+ {
1033
+ style: {
1034
+ textAlign: "center",
1035
+ color: c.subtle,
1036
+ fontSize: 12,
1037
+ fontWeight: 500,
1038
+ padding: "8px 0",
1039
+ ...fadeSlideIn(message.revealProgress, { distance: 0 })
1040
+ },
1041
+ children: text
1042
+ }
1043
+ );
1044
+ };
1045
+ var Composer3 = ({ theme, composer }) => {
1046
+ const c = IMESSAGE_COLORS[theme];
1047
+ const hasText = composer.text.length > 0;
1048
+ return /* @__PURE__ */ jsxs(
1049
+ "div",
1050
+ {
1051
+ style: {
1052
+ flex: "0 0 auto",
1053
+ display: "flex",
1054
+ alignItems: "flex-end",
1055
+ gap: 8,
1056
+ padding: "8px 12px"
1057
+ },
1058
+ children: [
1059
+ /* @__PURE__ */ jsx(
1060
+ "span",
1061
+ {
1062
+ style: {
1063
+ width: 30,
1064
+ height: 30,
1065
+ borderRadius: "50%",
1066
+ background: theme === "dark" ? "#1c1c1e" : "#e9e9eb",
1067
+ color: c.subtle,
1068
+ display: "flex",
1069
+ alignItems: "center",
1070
+ justifyContent: "center",
1071
+ fontSize: 20
1072
+ },
1073
+ children: "+"
1074
+ }
1075
+ ),
1076
+ /* @__PURE__ */ jsx(
1077
+ "div",
1078
+ {
1079
+ style: {
1080
+ flex: 1,
1081
+ minHeight: 34,
1082
+ display: "flex",
1083
+ alignItems: "center",
1084
+ border: `1px solid ${c.composerBorder}`,
1085
+ borderRadius: 18,
1086
+ padding: "5px 12px",
1087
+ background: c.composerBg,
1088
+ color: c.text,
1089
+ fontSize: 16
1090
+ },
1091
+ children: hasText ? /* @__PURE__ */ jsxs("span", { children: [
1092
+ composer.text,
1093
+ /* @__PURE__ */ jsx("span", { style: { color: c.selfBubble }, children: "|" })
1094
+ ] }) : /* @__PURE__ */ jsx("span", { style: { color: c.placeholder }, children: "iMessage" })
1095
+ }
1096
+ ),
1097
+ hasText ? /* @__PURE__ */ jsx(
1098
+ "span",
1099
+ {
1100
+ style: {
1101
+ width: 30,
1102
+ height: 30,
1103
+ borderRadius: "50%",
1104
+ background: c.selfBubble,
1105
+ color: "#fff",
1106
+ display: "flex",
1107
+ alignItems: "center",
1108
+ justifyContent: "center",
1109
+ fontSize: 17
1110
+ },
1111
+ children: "\u2191"
1112
+ }
1113
+ ) : null
1114
+ ]
1115
+ }
1116
+ );
1117
+ };
1118
+ var KEY_ROWS = [
1119
+ ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"],
1120
+ ["a", "s", "d", "f", "g", "h", "j", "k", "l"],
1121
+ ["\u21E7", "z", "x", "c", "v", "b", "n", "m", "\u232B"]
1122
+ ];
1123
+ var Keyboard = ({ theme }) => {
1124
+ const c = IMESSAGE_COLORS[theme];
1125
+ const key = (label, wide = false) => /* @__PURE__ */ jsx(
1126
+ "span",
1127
+ {
1128
+ style: {
1129
+ flex: wide ? 1.6 : 1,
1130
+ textAlign: "center",
1131
+ padding: "9px 0",
1132
+ borderRadius: 5,
1133
+ background: label === "\u21E7" || label === "\u232B" ? "transparent" : c.keyBg,
1134
+ color: c.keyText,
1135
+ fontSize: 16,
1136
+ fontWeight: 400,
1137
+ boxShadow: label === "\u21E7" || label === "\u232B" ? "none" : `0 1px 0 ${c.keyShadow}`,
1138
+ textTransform: label.length === 1 ? "uppercase" : "none"
1139
+ },
1140
+ children: label
1141
+ },
1142
+ label
1143
+ );
1144
+ return /* @__PURE__ */ jsxs(
1145
+ "div",
1146
+ {
1147
+ style: {
1148
+ flex: "0 0 auto",
1149
+ background: c.keyboardBg,
1150
+ padding: "6px 3px 4px",
1151
+ display: "flex",
1152
+ flexDirection: "column",
1153
+ gap: 7
1154
+ },
1155
+ children: [
1156
+ KEY_ROWS.map((row, i) => /* @__PURE__ */ jsx(
1157
+ "div",
1158
+ {
1159
+ style: {
1160
+ display: "flex",
1161
+ gap: 5,
1162
+ padding: i === 1 ? "0 18px" : "0 3px"
1163
+ },
1164
+ children: row.map((k) => key(k, k === "\u21E7" || k === "\u232B"))
1165
+ },
1166
+ i
1167
+ )),
1168
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 5, padding: "0 3px" }, children: [
1169
+ key("123", true),
1170
+ key("space", false),
1171
+ key("return", true)
1172
+ ] })
1173
+ ]
1174
+ }
1175
+ );
1176
+ };
1177
+ var Frame3 = ({
1178
+ theme,
1179
+ options,
1180
+ children
1181
+ }) => {
1182
+ const c = IMESSAGE_COLORS[theme];
1183
+ const contact = typeof options?.contact === "string" ? options.contact : "Messages";
1184
+ const showKeyboard = options?.keyboard !== false;
1185
+ return /* @__PURE__ */ jsxs(
1186
+ "div",
1187
+ {
1188
+ style: {
1189
+ fontFamily: IMESSAGE_FONT_STACK,
1190
+ background: c.bg,
1191
+ color: c.text,
1192
+ display: "flex",
1193
+ flexDirection: "column",
1194
+ height: "100%",
1195
+ width: "100%",
1196
+ WebkitFontSmoothing: "antialiased"
1197
+ },
1198
+ children: [
1199
+ /* @__PURE__ */ jsx(StatusBar, { theme }),
1200
+ /* @__PURE__ */ jsx(NavBar, { theme, title: contact }),
1201
+ /* @__PURE__ */ jsx(
1202
+ "div",
1203
+ {
1204
+ style: {
1205
+ flex: "1 1 auto",
1206
+ minHeight: 0,
1207
+ display: "flex",
1208
+ flexDirection: "column",
1209
+ justifyContent: "flex-end",
1210
+ overflow: "hidden",
1211
+ paddingBottom: 4
1212
+ },
1213
+ children
1214
+ }
1215
+ ),
1216
+ showKeyboard ? /* @__PURE__ */ jsx(Keyboard, { theme }) : null
1217
+ ]
1218
+ }
1219
+ );
1220
+ };
1221
+ var imessageComponents = {
1222
+ Frame: Frame3,
1223
+ Message: Message3,
1224
+ TypingIndicator: TypingIndicator3,
1225
+ Reaction: Reaction3,
1226
+ Composer: Composer3,
1227
+ SystemMessage: SystemMessage3,
1228
+ Avatar: Avatar3
1229
+ };
1230
+
1231
+ // src/imessage/capabilities.ts
1232
+ var imessageCapabilities = {
1233
+ events: {
1234
+ message: "native",
1235
+ composerType: "native",
1236
+ send: "native",
1237
+ typing: "native",
1238
+ // dot bubble
1239
+ reaction: "native",
1240
+ // tapbacks
1241
+ readReceipt: "native",
1242
+ // "Delivered" / "Read"
1243
+ edit: "native",
1244
+ delete: "native",
1245
+ system: "fallback",
1246
+ // rendered as centered grey text, not an app card
1247
+ beat: "native"
1248
+ },
1249
+ content: {
1250
+ text: true,
1251
+ image: true
1252
+ },
1253
+ reactions: true,
1254
+ threads: false,
1255
+ readReceipts: true
1256
+ };
1257
+
1258
+ // src/imessage/fonts.ts
1259
+ var imessageFonts = [
1260
+ {
1261
+ family: "Inter",
1262
+ intended: "SF Pro",
1263
+ weights: [400, 500, 600],
1264
+ sources: [
1265
+ {
1266
+ url: "https://cdn.jsdelivr.net/fontsource/fonts/inter@latest/latin-400-normal.woff2",
1267
+ weight: 400,
1268
+ format: "woff2"
1269
+ },
1270
+ {
1271
+ url: "https://cdn.jsdelivr.net/fontsource/fonts/inter@latest/latin-600-normal.woff2",
1272
+ weight: 600,
1273
+ format: "woff2"
1274
+ }
1275
+ ]
1276
+ }
1277
+ ];
1278
+
1279
+ // src/imessage/index.ts
1280
+ var imessageOptionsSchema = z.object({
1281
+ /** Contact name shown in the nav bar. */
1282
+ contact: z.string().optional(),
1283
+ /** Show the on-screen keyboard (default true). */
1284
+ keyboard: z.boolean().optional()
1285
+ });
1286
+ var imessage = defineSkin({
1287
+ id: "imessage",
1288
+ meta: {
1289
+ name: "iMessage (iOS)",
1290
+ defaultCanvas: { width: 390, height: 844 },
1291
+ supportsThemes: ["light", "dark"],
1292
+ capabilities: imessageCapabilities,
1293
+ optionsSchema: imessageOptionsSchema,
1294
+ fonts: imessageFonts
1295
+ },
1296
+ components: imessageComponents,
1297
+ tokens: imessageTokens
1298
+ });
1299
+
1300
+ // src/whatsapp/tokens.ts
1301
+ var WHATSAPP_COLORS = {
1302
+ light: {
1303
+ wallpaper: "#efeae2",
1304
+ header: "#008069",
1305
+ headerText: "#ffffff",
1306
+ headerSubtle: "rgba(255,255,255,0.8)",
1307
+ text: "#111b21",
1308
+ subtle: "#667781",
1309
+ selfBubble: "#d9fdd3",
1310
+ selfText: "#111b21",
1311
+ otherBubble: "#ffffff",
1312
+ otherText: "#111b21",
1313
+ bubbleTime: "#667781",
1314
+ tick: "#53bdeb",
1315
+ composerBar: "#f0f2f5",
1316
+ inputBg: "#ffffff",
1317
+ placeholder: "#8696a0",
1318
+ accent: "#00a884",
1319
+ reactionBg: "#ffffff"
1320
+ },
1321
+ dark: {
1322
+ wallpaper: "#0b141a",
1323
+ header: "#202c33",
1324
+ headerText: "#e9edef",
1325
+ headerSubtle: "#8696a0",
1326
+ text: "#e9edef",
1327
+ subtle: "#8696a0",
1328
+ selfBubble: "#005c4b",
1329
+ selfText: "#e9edef",
1330
+ otherBubble: "#202c33",
1331
+ otherText: "#e9edef",
1332
+ bubbleTime: "#8696a0",
1333
+ tick: "#53bdeb",
1334
+ composerBar: "#202c33",
1335
+ inputBg: "#2a3942",
1336
+ placeholder: "#8696a0",
1337
+ accent: "#00a884",
1338
+ reactionBg: "#2a3942"
1339
+ }
1340
+ };
1341
+ var WHATSAPP_FONT_STACK = '"Helvetica Neue", Helvetica, -apple-system, "Segoe UI", Roboto, Arial, sans-serif';
1342
+ var whatsappTokens = {
1343
+ light: {
1344
+ colors: WHATSAPP_COLORS.light
1345
+ },
1346
+ dark: { colors: WHATSAPP_COLORS.dark }
1347
+ };
1348
+ var RADIUS2 = 8;
1349
+ function formatTime2(atMs) {
1350
+ const base = 9 * 3600 * 1e3;
1351
+ const total = Math.floor((base + atMs) / 1e3);
1352
+ const h = Math.floor(total / 3600) % 24;
1353
+ const m = Math.floor(total % 3600 / 60);
1354
+ const ampm = h >= 12 ? "PM" : "AM";
1355
+ const hr = h % 12 === 0 ? 12 : h % 12;
1356
+ return `${hr}:${String(m).padStart(2, "0")} ${ampm}`;
1357
+ }
1358
+ function initials3(name) {
1359
+ return name.split(/\s+/).map((w) => w.charAt(0)).slice(0, 2).join("").toUpperCase();
1360
+ }
1361
+ var Avatar4 = ({ participant, size = 40 }) => {
1362
+ if (participant.avatar) {
1363
+ return /* @__PURE__ */ jsx(
1364
+ "img",
1365
+ {
1366
+ src: participant.avatar,
1367
+ alt: participant.name,
1368
+ width: size,
1369
+ height: size,
1370
+ style: {
1371
+ width: size,
1372
+ height: size,
1373
+ borderRadius: "50%",
1374
+ objectFit: "cover"
1375
+ }
1376
+ }
1377
+ );
1378
+ }
1379
+ return /* @__PURE__ */ jsx(
1380
+ "div",
1381
+ {
1382
+ style: {
1383
+ width: size,
1384
+ height: size,
1385
+ borderRadius: "50%",
1386
+ background: participant.color ?? "#6a7175",
1387
+ color: "#fff",
1388
+ display: "flex",
1389
+ alignItems: "center",
1390
+ justifyContent: "center",
1391
+ fontSize: size * 0.4,
1392
+ fontWeight: 500
1393
+ },
1394
+ children: initials3(participant.name)
1395
+ }
1396
+ );
1397
+ };
1398
+ var DoubleTick = ({ color }) => /* @__PURE__ */ jsx("span", { style: { color, fontSize: 13, letterSpacing: -3, marginLeft: 3 }, children: "\u2713\u2713" });
1399
+ var Reaction4 = ({ theme, reaction }) => {
1400
+ const c = WHATSAPP_COLORS[theme];
1401
+ return /* @__PURE__ */ jsx(
1402
+ "span",
1403
+ {
1404
+ style: {
1405
+ ...popIn(reaction.progress),
1406
+ display: "inline-flex",
1407
+ alignItems: "center",
1408
+ background: c.reactionBg,
1409
+ borderRadius: 12,
1410
+ padding: "1px 5px",
1411
+ fontSize: 12,
1412
+ boxShadow: `0 1px 2px rgba(0,0,0,${theme === "dark" ? 0.4 : 0.18})`
1413
+ },
1414
+ children: reaction.emoji
1415
+ }
1416
+ );
1417
+ };
1418
+ var Message4 = ({ theme, message }) => {
1419
+ const c = WHATSAPP_COLORS[theme];
1420
+ const self = message.isSelf;
1421
+ const bubble = {
1422
+ position: "relative",
1423
+ maxWidth: "78%",
1424
+ padding: "6px 8px 5px 9px",
1425
+ borderRadius: RADIUS2,
1426
+ background: self ? c.selfBubble : c.otherBubble,
1427
+ color: self ? c.selfText : c.otherText,
1428
+ fontSize: 14.2,
1429
+ lineHeight: 1.32,
1430
+ wordBreak: "break-word",
1431
+ boxShadow: `0 1px 0.5px rgba(0,0,0,${theme === "dark" ? 0.2 : 0.13})`,
1432
+ ...self ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 }
1433
+ };
1434
+ return /* @__PURE__ */ jsx(
1435
+ "div",
1436
+ {
1437
+ style: {
1438
+ display: "flex",
1439
+ justifyContent: self ? "flex-end" : "flex-start",
1440
+ padding: message.isGrouped ? "1px 12px" : "3px 12px",
1441
+ ...fadeSlideIn(message.revealProgress, { distance: 5 })
1442
+ },
1443
+ children: /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
1444
+ /* @__PURE__ */ jsxs("div", { style: bubble, children: [
1445
+ /* @__PURE__ */ jsx(
1446
+ MessageContent,
1447
+ {
1448
+ nodes: message.content,
1449
+ imageStyle: { borderRadius: 6, maxWidth: 240, marginBottom: 2 }
1450
+ }
1451
+ ),
1452
+ /* @__PURE__ */ jsxs(
1453
+ "span",
1454
+ {
1455
+ style: {
1456
+ float: "right",
1457
+ marginLeft: 8,
1458
+ marginTop: 2,
1459
+ fontSize: 11,
1460
+ color: c.bubbleTime,
1461
+ display: "inline-flex",
1462
+ alignItems: "center",
1463
+ whiteSpace: "nowrap"
1464
+ },
1465
+ children: [
1466
+ formatTime2(message.atMs),
1467
+ self ? /* @__PURE__ */ jsx(DoubleTick, { color: c.tick }) : null
1468
+ ]
1469
+ }
1470
+ )
1471
+ ] }),
1472
+ message.reactions.length > 0 ? /* @__PURE__ */ jsx(
1473
+ "div",
1474
+ {
1475
+ style: {
1476
+ position: "absolute",
1477
+ bottom: -10,
1478
+ ...self ? { right: 8 } : { left: 8 },
1479
+ display: "flex",
1480
+ gap: 2
1481
+ },
1482
+ children: message.reactions.map((r, i) => /* @__PURE__ */ jsx(Reaction4, { theme, reaction: r }, i))
1483
+ }
1484
+ ) : null
1485
+ ] })
1486
+ }
1487
+ );
1488
+ };
1489
+ var TypingIndicator4 = ({ theme, typing }) => {
1490
+ const c = WHATSAPP_COLORS[theme];
1491
+ return /* @__PURE__ */ jsx(
1492
+ "div",
1493
+ {
1494
+ style: {
1495
+ display: "flex",
1496
+ justifyContent: "flex-start",
1497
+ padding: "3px 12px"
1498
+ },
1499
+ children: /* @__PURE__ */ jsx(
1500
+ "div",
1501
+ {
1502
+ style: {
1503
+ background: c.otherBubble,
1504
+ borderRadius: RADIUS2,
1505
+ borderTopLeftRadius: 0,
1506
+ padding: "9px 12px",
1507
+ boxShadow: `0 1px 0.5px rgba(0,0,0,${theme === "dark" ? 0.2 : 0.13})`
1508
+ },
1509
+ children: /* @__PURE__ */ jsx(
1510
+ TypingDots,
1511
+ {
1512
+ progress: typing.progress,
1513
+ color: c.subtle,
1514
+ size: 7,
1515
+ gap: 4
1516
+ }
1517
+ )
1518
+ }
1519
+ )
1520
+ }
1521
+ );
1522
+ };
1523
+ var SystemMessage4 = ({ theme, message }) => {
1524
+ const c = WHATSAPP_COLORS[theme];
1525
+ const text = message.content.map(
1526
+ (n) => n.type === "text" ? n.spans.map((s) => s.value ?? "").join("") : ""
1527
+ ).join(" ");
1528
+ return /* @__PURE__ */ jsx(
1529
+ "div",
1530
+ {
1531
+ style: {
1532
+ display: "flex",
1533
+ justifyContent: "center",
1534
+ padding: "6px 0",
1535
+ ...fadeSlideIn(message.revealProgress, { distance: 0 })
1536
+ },
1537
+ children: /* @__PURE__ */ jsx(
1538
+ "span",
1539
+ {
1540
+ style: {
1541
+ background: theme === "dark" ? "#182229" : "#ffffff",
1542
+ color: c.subtle,
1543
+ fontSize: 12.5,
1544
+ padding: "5px 12px",
1545
+ borderRadius: 8,
1546
+ boxShadow: `0 1px 0.5px rgba(0,0,0,0.13)`
1547
+ },
1548
+ children: text
1549
+ }
1550
+ )
1551
+ }
1552
+ );
1553
+ };
1554
+ var Composer4 = ({ theme, composer }) => {
1555
+ const c = WHATSAPP_COLORS[theme];
1556
+ const hasText = composer.text.length > 0;
1557
+ return /* @__PURE__ */ jsxs(
1558
+ "div",
1559
+ {
1560
+ style: {
1561
+ flex: "0 0 auto",
1562
+ display: "flex",
1563
+ alignItems: "flex-end",
1564
+ gap: 8,
1565
+ padding: "8px 10px",
1566
+ background: c.composerBar
1567
+ },
1568
+ children: [
1569
+ /* @__PURE__ */ jsxs(
1570
+ "div",
1571
+ {
1572
+ style: {
1573
+ flex: 1,
1574
+ minHeight: 40,
1575
+ display: "flex",
1576
+ alignItems: "center",
1577
+ gap: 8,
1578
+ background: c.inputBg,
1579
+ borderRadius: 22,
1580
+ padding: "8px 14px",
1581
+ color: c.text,
1582
+ fontSize: 15
1583
+ },
1584
+ children: [
1585
+ /* @__PURE__ */ jsx("span", { style: { color: c.subtle, fontSize: 18 }, children: "\u{1F642}" }),
1586
+ hasText ? /* @__PURE__ */ jsxs("span", { children: [
1587
+ composer.text,
1588
+ /* @__PURE__ */ jsx("span", { style: { color: c.accent }, children: "|" })
1589
+ ] }) : /* @__PURE__ */ jsx("span", { style: { color: c.placeholder }, children: "Message" })
1590
+ ]
1591
+ }
1592
+ ),
1593
+ /* @__PURE__ */ jsx(
1594
+ "span",
1595
+ {
1596
+ style: {
1597
+ width: 40,
1598
+ height: 40,
1599
+ borderRadius: "50%",
1600
+ background: c.accent,
1601
+ color: "#fff",
1602
+ display: "flex",
1603
+ alignItems: "center",
1604
+ justifyContent: "center",
1605
+ fontSize: 18
1606
+ },
1607
+ children: hasText ? "\u27A4" : "\u{1F3A4}"
1608
+ }
1609
+ )
1610
+ ]
1611
+ }
1612
+ );
1613
+ };
1614
+ var Frame4 = ({
1615
+ theme,
1616
+ options,
1617
+ children
1618
+ }) => {
1619
+ const c = WHATSAPP_COLORS[theme];
1620
+ const contact = typeof options?.contact === "string" ? options.contact : "WhatsApp";
1621
+ const status = typeof options?.status === "string" ? options.status : "online";
1622
+ return /* @__PURE__ */ jsxs(
1623
+ "div",
1624
+ {
1625
+ style: {
1626
+ fontFamily: WHATSAPP_FONT_STACK,
1627
+ background: c.wallpaper,
1628
+ color: c.text,
1629
+ display: "flex",
1630
+ flexDirection: "column",
1631
+ height: "100%",
1632
+ width: "100%",
1633
+ WebkitFontSmoothing: "antialiased"
1634
+ },
1635
+ children: [
1636
+ /* @__PURE__ */ jsxs(
1637
+ "div",
1638
+ {
1639
+ style: {
1640
+ flex: "0 0 auto",
1641
+ display: "flex",
1642
+ alignItems: "center",
1643
+ gap: 10,
1644
+ padding: "8px 12px",
1645
+ background: c.header,
1646
+ color: c.headerText
1647
+ },
1648
+ children: [
1649
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 22, marginRight: -2 }, children: "\u2039" }),
1650
+ /* @__PURE__ */ jsx(
1651
+ "div",
1652
+ {
1653
+ style: {
1654
+ width: 38,
1655
+ height: 38,
1656
+ borderRadius: "50%",
1657
+ background: "#6a7175",
1658
+ color: "#fff",
1659
+ display: "flex",
1660
+ alignItems: "center",
1661
+ justifyContent: "center",
1662
+ fontSize: 15,
1663
+ fontWeight: 500
1664
+ },
1665
+ children: initials3(contact)
1666
+ }
1667
+ ),
1668
+ /* @__PURE__ */ jsxs(
1669
+ "div",
1670
+ {
1671
+ style: { display: "flex", flexDirection: "column", lineHeight: 1.2 },
1672
+ children: [
1673
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 16, fontWeight: 600 }, children: contact }),
1674
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: c.headerSubtle }, children: status })
1675
+ ]
1676
+ }
1677
+ )
1678
+ ]
1679
+ }
1680
+ ),
1681
+ /* @__PURE__ */ jsx(
1682
+ "div",
1683
+ {
1684
+ style: {
1685
+ flex: "1 1 auto",
1686
+ minHeight: 0,
1687
+ display: "flex",
1688
+ flexDirection: "column",
1689
+ justifyContent: "flex-end",
1690
+ overflow: "hidden",
1691
+ padding: "6px 0"
1692
+ },
1693
+ children
1694
+ }
1695
+ )
1696
+ ]
1697
+ }
1698
+ );
1699
+ };
1700
+ var whatsappComponents = {
1701
+ Frame: Frame4,
1702
+ Message: Message4,
1703
+ TypingIndicator: TypingIndicator4,
1704
+ Reaction: Reaction4,
1705
+ Composer: Composer4,
1706
+ SystemMessage: SystemMessage4,
1707
+ Avatar: Avatar4
1708
+ };
1709
+
1710
+ // src/whatsapp/capabilities.ts
1711
+ var whatsappCapabilities = {
1712
+ events: {
1713
+ message: "native",
1714
+ composerType: "native",
1715
+ send: "native",
1716
+ typing: "native",
1717
+ reaction: "native",
1718
+ readReceipt: "native",
1719
+ // double ticks
1720
+ edit: "native",
1721
+ delete: "native",
1722
+ system: "fallback",
1723
+ // centred system pill
1724
+ beat: "native"
1725
+ },
1726
+ content: {
1727
+ text: true,
1728
+ image: true
1729
+ },
1730
+ reactions: true,
1731
+ threads: false,
1732
+ readReceipts: true
1733
+ };
1734
+
1735
+ // src/whatsapp/index.ts
1736
+ var whatsappOptionsSchema = z.object({
1737
+ /** Contact / group name in the header. */
1738
+ contact: z.string().optional(),
1739
+ /** Header subtitle (e.g. `"online"`, `"last seen recently"`). */
1740
+ status: z.string().optional()
1741
+ });
1742
+ var whatsapp = defineSkin({
1743
+ id: "whatsapp",
1744
+ meta: {
1745
+ name: "WhatsApp",
1746
+ defaultCanvas: { width: 390, height: 760 },
1747
+ supportsThemes: ["light", "dark"],
1748
+ capabilities: whatsappCapabilities,
1749
+ optionsSchema: whatsappOptionsSchema
1750
+ },
1751
+ components: whatsappComponents,
1752
+ tokens: whatsappTokens
1753
+ });
1754
+
1755
+ // src/cursor/tokens.ts
1756
+ var CURSOR_COLORS = {
1757
+ dark: {
1758
+ bg: "#1a1a1a",
1759
+ header: "#1a1a1a",
1760
+ border: "#2d2d2d",
1761
+ text: "#d4d4d4",
1762
+ dim: "#858585",
1763
+ userBg: "#262626",
1764
+ userBorder: "#333333",
1765
+ codeBg: "#2a2a2a",
1766
+ codeText: "#ce9178",
1767
+ accent: "#4d9fff",
1768
+ composerBg: "#202020",
1769
+ composerBorder: "#3a3a3a",
1770
+ placeholder: "#6e6e6e",
1771
+ chipBg: "#2a2a2a",
1772
+ link: "#4d9fff"
1773
+ },
1774
+ light: {
1775
+ bg: "#ffffff",
1776
+ header: "#ffffff",
1777
+ border: "#e8e8e8",
1778
+ text: "#1e1e1e",
1779
+ dim: "#6e6e6e",
1780
+ userBg: "#f4f4f4",
1781
+ userBorder: "#e8e8e8",
1782
+ codeBg: "#f0f0f0",
1783
+ codeText: "#a31515",
1784
+ accent: "#0a72ff",
1785
+ composerBg: "#f9f9f9",
1786
+ composerBorder: "#e2e2e2",
1787
+ placeholder: "#9a9a9a",
1788
+ chipBg: "#f0f0f0",
1789
+ link: "#0a72ff"
1790
+ }
1791
+ };
1792
+ var CURSOR_FONT_STACK = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif';
1793
+ var cursorTokens = {
1794
+ light: { colors: CURSOR_COLORS.light },
1795
+ dark: { colors: CURSOR_COLORS.dark }
1796
+ };
1797
+ function markStyles3(c) {
1798
+ return {
1799
+ link: { color: c.link, textDecoration: "none" },
1800
+ code: {
1801
+ fontFamily: "Menlo, Monaco, monospace",
1802
+ fontSize: "0.86em",
1803
+ background: c.codeBg,
1804
+ color: c.codeText,
1805
+ borderRadius: 4,
1806
+ padding: "1px 4px"
1807
+ }
1808
+ };
1809
+ }
1810
+ var Avatar5 = () => null;
1811
+ var Reaction5 = () => null;
1812
+ var Message5 = ({ theme, message }) => {
1813
+ const c = CURSOR_COLORS[theme];
1814
+ const self = message.isSelf;
1815
+ if (self) {
1816
+ return /* @__PURE__ */ jsx(
1817
+ "div",
1818
+ {
1819
+ style: { padding: "5px 12px", ...fadeSlideIn(message.revealProgress) },
1820
+ children: /* @__PURE__ */ jsx(
1821
+ "div",
1822
+ {
1823
+ style: {
1824
+ background: c.userBg,
1825
+ border: `1px solid ${c.userBorder}`,
1826
+ borderRadius: 8,
1827
+ padding: "8px 11px",
1828
+ color: c.text,
1829
+ fontSize: 13,
1830
+ lineHeight: 1.5
1831
+ },
1832
+ children: /* @__PURE__ */ jsx(MessageContent, { nodes: message.content, styles: markStyles3(c) })
1833
+ }
1834
+ )
1835
+ }
1836
+ );
1837
+ }
1838
+ return /* @__PURE__ */ jsx(
1839
+ "div",
1840
+ {
1841
+ style: {
1842
+ padding: "5px 12px 9px",
1843
+ color: c.text,
1844
+ fontSize: 13,
1845
+ lineHeight: 1.6,
1846
+ ...fadeSlideIn(message.revealProgress)
1847
+ },
1848
+ children: /* @__PURE__ */ jsx(MessageContent, { nodes: message.content, styles: markStyles3(c) })
1849
+ }
1850
+ );
1851
+ };
1852
+ var SystemMessage5 = ({ theme, message }) => {
1853
+ const c = CURSOR_COLORS[theme];
1854
+ const text = message.content.map(
1855
+ (n) => n.type === "text" ? n.spans.map((s) => s.value ?? "").join("") : ""
1856
+ ).join(" ");
1857
+ return /* @__PURE__ */ jsx(
1858
+ "div",
1859
+ {
1860
+ style: {
1861
+ margin: "4px 12px",
1862
+ padding: "6px 10px",
1863
+ borderLeft: `2px solid ${c.accent}`,
1864
+ background: c.userBg,
1865
+ borderRadius: 4,
1866
+ color: c.dim,
1867
+ fontSize: 12,
1868
+ fontFamily: "Menlo, monospace",
1869
+ ...fadeSlideIn(message.revealProgress, { distance: 0 })
1870
+ },
1871
+ children: text
1872
+ }
1873
+ );
1874
+ };
1875
+ var TypingIndicator5 = ({ theme, typing }) => {
1876
+ const c = CURSOR_COLORS[theme];
1877
+ return /* @__PURE__ */ jsxs(
1878
+ "div",
1879
+ {
1880
+ style: {
1881
+ display: "flex",
1882
+ alignItems: "center",
1883
+ gap: 7,
1884
+ padding: "5px 12px",
1885
+ color: c.dim,
1886
+ fontSize: 12.5
1887
+ },
1888
+ children: [
1889
+ /* @__PURE__ */ jsx(TypingDots, { progress: typing.progress, color: c.accent, size: 5 }),
1890
+ "Generating\u2026"
1891
+ ]
1892
+ }
1893
+ );
1894
+ };
1895
+ var Composer5 = ({ theme, composer }) => {
1896
+ const c = CURSOR_COLORS[theme];
1897
+ const hasText = composer.text.length > 0;
1898
+ const chip = {
1899
+ fontSize: 11,
1900
+ color: c.dim,
1901
+ background: c.chipBg,
1902
+ borderRadius: 5,
1903
+ padding: "2px 7px"
1904
+ };
1905
+ return /* @__PURE__ */ jsx("div", { style: { flex: "0 0 auto", padding: "8px 12px 12px" }, children: /* @__PURE__ */ jsxs(
1906
+ "div",
1907
+ {
1908
+ style: {
1909
+ border: `1px solid ${c.composerBorder}`,
1910
+ borderRadius: 10,
1911
+ background: c.composerBg,
1912
+ padding: "9px 11px",
1913
+ color: c.text,
1914
+ fontSize: 13
1915
+ },
1916
+ children: [
1917
+ /* @__PURE__ */ jsx("div", { style: { minHeight: 18 }, children: hasText ? /* @__PURE__ */ jsxs("span", { children: [
1918
+ composer.text,
1919
+ /* @__PURE__ */ jsx("span", { style: { color: c.accent }, children: "\u258D" })
1920
+ ] }) : /* @__PURE__ */ jsx("span", { style: { color: c.placeholder }, children: "Plan, search, build anything" }) }),
1921
+ /* @__PURE__ */ jsxs(
1922
+ "div",
1923
+ {
1924
+ style: {
1925
+ display: "flex",
1926
+ alignItems: "center",
1927
+ justifyContent: "space-between",
1928
+ marginTop: 9
1929
+ },
1930
+ children: [
1931
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6 }, children: [
1932
+ /* @__PURE__ */ jsx("span", { style: chip, children: "\u221E Agent" }),
1933
+ /* @__PURE__ */ jsx("span", { style: chip, children: "claude-4.5-sonnet" })
1934
+ ] }),
1935
+ /* @__PURE__ */ jsx(
1936
+ "span",
1937
+ {
1938
+ style: {
1939
+ width: 22,
1940
+ height: 22,
1941
+ borderRadius: 6,
1942
+ background: hasText ? c.accent : c.chipBg,
1943
+ color: hasText ? "#fff" : c.dim,
1944
+ display: "flex",
1945
+ alignItems: "center",
1946
+ justifyContent: "center",
1947
+ fontSize: 13
1948
+ },
1949
+ children: "\u2191"
1950
+ }
1951
+ )
1952
+ ]
1953
+ }
1954
+ )
1955
+ ]
1956
+ }
1957
+ ) });
1958
+ };
1959
+ var Frame5 = ({
1960
+ theme,
1961
+ options,
1962
+ children
1963
+ }) => {
1964
+ const c = CURSOR_COLORS[theme];
1965
+ const title = typeof options?.title === "string" ? options.title : "Chat";
1966
+ return /* @__PURE__ */ jsxs(
1967
+ "div",
1968
+ {
1969
+ style: {
1970
+ fontFamily: CURSOR_FONT_STACK,
1971
+ background: c.bg,
1972
+ color: c.text,
1973
+ display: "flex",
1974
+ flexDirection: "column",
1975
+ height: "100%",
1976
+ width: "100%",
1977
+ WebkitFontSmoothing: "antialiased"
1978
+ },
1979
+ children: [
1980
+ /* @__PURE__ */ jsxs(
1981
+ "div",
1982
+ {
1983
+ style: {
1984
+ flex: "0 0 auto",
1985
+ display: "flex",
1986
+ alignItems: "center",
1987
+ gap: 8,
1988
+ padding: "8px 12px",
1989
+ borderBottom: `1px solid ${c.border}`,
1990
+ fontSize: 12,
1991
+ color: c.dim
1992
+ },
1993
+ children: [
1994
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: c.text }, children: title }),
1995
+ /* @__PURE__ */ jsx("span", { style: { marginLeft: "auto", fontSize: 14 }, children: "\uFF0B" }),
1996
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 14 }, children: "\u22EF" })
1997
+ ]
1998
+ }
1999
+ ),
2000
+ /* @__PURE__ */ jsx(
2001
+ "div",
2002
+ {
2003
+ style: {
2004
+ flex: "1 1 auto",
2005
+ minHeight: 0,
2006
+ display: "flex",
2007
+ flexDirection: "column",
2008
+ justifyContent: "flex-end",
2009
+ overflow: "hidden",
2010
+ padding: "6px 0"
2011
+ },
2012
+ children
2013
+ }
2014
+ )
2015
+ ]
2016
+ }
2017
+ );
2018
+ };
2019
+ var cursorComponents = {
2020
+ Frame: Frame5,
2021
+ Message: Message5,
2022
+ TypingIndicator: TypingIndicator5,
2023
+ Reaction: Reaction5,
2024
+ Composer: Composer5,
2025
+ SystemMessage: SystemMessage5,
2026
+ Avatar: Avatar5
2027
+ };
2028
+
2029
+ // src/cursor/index.ts
2030
+ var cursorCapabilities = {
2031
+ events: {
2032
+ message: "native",
2033
+ composerType: "native",
2034
+ send: "native",
2035
+ typing: "native",
2036
+ system: "native",
2037
+ reaction: "unsupported",
2038
+ readReceipt: "unsupported",
2039
+ edit: "native",
2040
+ delete: "native",
2041
+ beat: "native"
2042
+ },
2043
+ content: { text: true, image: true },
2044
+ reactions: false,
2045
+ threads: false,
2046
+ readReceipts: false
2047
+ };
2048
+ var cursorOptionsSchema = z.object({
2049
+ title: z.string().optional()
2050
+ });
2051
+ var cursor = defineSkin({
2052
+ id: "cursor",
2053
+ meta: {
2054
+ name: "Cursor panel",
2055
+ defaultCanvas: { width: 400, height: 600 },
2056
+ supportsThemes: ["dark", "light"],
2057
+ capabilities: cursorCapabilities,
2058
+ optionsSchema: cursorOptionsSchema
2059
+ },
2060
+ components: cursorComponents,
2061
+ tokens: cursorTokens
2062
+ });
2063
+ var CHROME = {
2064
+ light: {
2065
+ window: "#ffffff",
2066
+ sidebar: "#f5f5f7",
2067
+ sidebarBorder: "#e0e0e2",
2068
+ titleBar: "#ececee",
2069
+ text: "#1d1d1f",
2070
+ subtle: "#86868b",
2071
+ activeRow: "#0b93f6",
2072
+ activeText: "#ffffff",
2073
+ searchBg: "#e4e4e6"
2074
+ },
2075
+ dark: {
2076
+ window: "#1e1e1e",
2077
+ sidebar: "#28282a",
2078
+ sidebarBorder: "#3a3a3c",
2079
+ titleBar: "#323234",
2080
+ text: "#f5f5f7",
2081
+ subtle: "#98989d",
2082
+ activeRow: "#0b6cff",
2083
+ activeText: "#ffffff",
2084
+ searchBg: "#3a3a3c"
2085
+ }
2086
+ };
2087
+ var TRAFFIC = ["#ff5f56", "#ffbd2e", "#27c93f"];
2088
+ function initials4(name) {
2089
+ return name.split(/\s+/).map((w) => w.charAt(0)).slice(0, 2).join("").toUpperCase();
2090
+ }
2091
+ var SAMPLE_CONVOS = [
2092
+ { name: "Sam Carter", preview: "you're the best, omw \u{1F3C3}", time: "9:41 AM" },
2093
+ { name: "Mum", preview: "call me when you can \u2764\uFE0F", time: "Yesterday" },
2094
+ { name: "Design", preview: "Tap to load preview", time: "Tuesday" },
2095
+ { name: "Alex Rivera", preview: "ship it \u{1F680}", time: "Monday" }
2096
+ ];
2097
+ var SidebarRow = ({ theme, name, preview, time, active }) => {
2098
+ const ch = CHROME[theme];
2099
+ return /* @__PURE__ */ jsxs(
2100
+ "div",
2101
+ {
2102
+ style: {
2103
+ display: "flex",
2104
+ gap: 10,
2105
+ padding: "8px 10px",
2106
+ borderRadius: 8,
2107
+ background: active ? ch.activeRow : "transparent",
2108
+ color: active ? ch.activeText : ch.text
2109
+ },
2110
+ children: [
2111
+ /* @__PURE__ */ jsx(
2112
+ "div",
2113
+ {
2114
+ style: {
2115
+ width: 40,
2116
+ height: 40,
2117
+ borderRadius: "50%",
2118
+ background: active ? "rgba(255,255,255,0.25)" : "#a9a9af",
2119
+ color: "#fff",
2120
+ display: "flex",
2121
+ alignItems: "center",
2122
+ justifyContent: "center",
2123
+ fontSize: 15,
2124
+ flex: "0 0 40px"
2125
+ },
2126
+ children: initials4(name)
2127
+ }
2128
+ ),
2129
+ /* @__PURE__ */ jsxs("div", { style: { minWidth: 0, flex: 1 }, children: [
2130
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
2131
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 14, fontWeight: 600 }, children: name }),
2132
+ /* @__PURE__ */ jsx(
2133
+ "span",
2134
+ {
2135
+ style: {
2136
+ fontSize: 11,
2137
+ color: active ? "rgba(255,255,255,0.8)" : ch.subtle
2138
+ },
2139
+ children: time
2140
+ }
2141
+ )
2142
+ ] }),
2143
+ /* @__PURE__ */ jsx(
2144
+ "div",
2145
+ {
2146
+ style: {
2147
+ fontSize: 13,
2148
+ color: active ? "rgba(255,255,255,0.85)" : ch.subtle,
2149
+ whiteSpace: "nowrap",
2150
+ overflow: "hidden",
2151
+ textOverflow: "ellipsis"
2152
+ },
2153
+ children: preview
2154
+ }
2155
+ )
2156
+ ] })
2157
+ ]
2158
+ }
2159
+ );
2160
+ };
2161
+ var Frame6 = ({
2162
+ theme,
2163
+ options,
2164
+ children
2165
+ }) => {
2166
+ const ch = CHROME[theme];
2167
+ const contact = typeof options?.contact === "string" ? options.contact : "Messages";
2168
+ const convos = [
2169
+ { name: contact, preview: "active now", time: "now" },
2170
+ ...SAMPLE_CONVOS.filter((c) => c.name !== contact)
2171
+ ];
2172
+ return /* @__PURE__ */ jsxs(
2173
+ "div",
2174
+ {
2175
+ style: {
2176
+ fontFamily: IMESSAGE_FONT_STACK,
2177
+ background: ch.window,
2178
+ color: ch.text,
2179
+ display: "flex",
2180
+ flexDirection: "column",
2181
+ height: "100%",
2182
+ width: "100%",
2183
+ WebkitFontSmoothing: "antialiased"
2184
+ },
2185
+ children: [
2186
+ /* @__PURE__ */ jsx(
2187
+ "div",
2188
+ {
2189
+ style: {
2190
+ flex: "0 0 auto",
2191
+ height: 38,
2192
+ background: ch.titleBar,
2193
+ display: "flex",
2194
+ alignItems: "center",
2195
+ gap: 8,
2196
+ padding: "0 13px",
2197
+ borderBottom: `1px solid ${ch.sidebarBorder}`
2198
+ },
2199
+ children: TRAFFIC.map((color) => /* @__PURE__ */ jsx(
2200
+ "span",
2201
+ {
2202
+ style: {
2203
+ width: 12,
2204
+ height: 12,
2205
+ borderRadius: "50%",
2206
+ background: color
2207
+ }
2208
+ },
2209
+ color
2210
+ ))
2211
+ }
2212
+ ),
2213
+ /* @__PURE__ */ jsxs("div", { style: { flex: "1 1 auto", minHeight: 0, display: "flex" }, children: [
2214
+ /* @__PURE__ */ jsxs(
2215
+ "div",
2216
+ {
2217
+ style: {
2218
+ flex: "0 0 250px",
2219
+ background: ch.sidebar,
2220
+ borderRight: `1px solid ${ch.sidebarBorder}`,
2221
+ display: "flex",
2222
+ flexDirection: "column",
2223
+ padding: "8px 8px 0"
2224
+ },
2225
+ children: [
2226
+ /* @__PURE__ */ jsx(
2227
+ "div",
2228
+ {
2229
+ style: {
2230
+ background: ch.searchBg,
2231
+ borderRadius: 7,
2232
+ padding: "5px 9px",
2233
+ color: ch.subtle,
2234
+ fontSize: 13,
2235
+ marginBottom: 6
2236
+ },
2237
+ children: "\u{1F50D} Search"
2238
+ }
2239
+ ),
2240
+ convos.slice(0, 5).map((cv, i) => /* @__PURE__ */ jsx(
2241
+ SidebarRow,
2242
+ {
2243
+ theme,
2244
+ name: cv.name,
2245
+ preview: cv.preview,
2246
+ time: cv.time,
2247
+ active: i === 0
2248
+ },
2249
+ cv.name
2250
+ ))
2251
+ ]
2252
+ }
2253
+ ),
2254
+ /* @__PURE__ */ jsxs(
2255
+ "div",
2256
+ {
2257
+ style: {
2258
+ flex: "1 1 auto",
2259
+ minWidth: 0,
2260
+ display: "flex",
2261
+ flexDirection: "column",
2262
+ background: ch.window
2263
+ },
2264
+ children: [
2265
+ /* @__PURE__ */ jsx(
2266
+ "div",
2267
+ {
2268
+ style: {
2269
+ flex: "0 0 auto",
2270
+ textAlign: "center",
2271
+ padding: "8px 0",
2272
+ borderBottom: `1px solid ${ch.sidebarBorder}`,
2273
+ fontSize: 13,
2274
+ fontWeight: 600
2275
+ },
2276
+ children: contact
2277
+ }
2278
+ ),
2279
+ /* @__PURE__ */ jsx(
2280
+ "div",
2281
+ {
2282
+ style: {
2283
+ flex: "1 1 auto",
2284
+ minHeight: 0,
2285
+ display: "flex",
2286
+ flexDirection: "column",
2287
+ justifyContent: "flex-end",
2288
+ overflow: "hidden",
2289
+ paddingBottom: 4
2290
+ },
2291
+ children
2292
+ }
2293
+ )
2294
+ ]
2295
+ }
2296
+ )
2297
+ ] })
2298
+ ]
2299
+ }
2300
+ );
2301
+ };
2302
+ var macosComponents = {
2303
+ ...imessageComponents,
2304
+ Frame: Frame6
2305
+ };
2306
+
2307
+ // src/messages-macos/index.ts
2308
+ var macosOptionsSchema = z.object({
2309
+ contact: z.string().optional()
2310
+ });
2311
+ var messagesMacos = defineSkin({
2312
+ id: "messages-macos",
2313
+ meta: {
2314
+ name: "Messages (macOS)",
2315
+ defaultCanvas: { width: 900, height: 600 },
2316
+ supportsThemes: ["light", "dark"],
2317
+ capabilities: imessageCapabilities,
2318
+ optionsSchema: macosOptionsSchema,
2319
+ fonts: imessageFonts
2320
+ },
2321
+ components: macosComponents,
2322
+ tokens: imessageTokens
2323
+ });
2324
+
2325
+ // src/discord/tokens.ts
2326
+ var DISCORD = {
2327
+ bg: "#313338",
2328
+ channelBarBorder: "#26282c",
2329
+ text: "#dbdee1",
2330
+ muted: "#949ba4",
2331
+ username: "#f2f3f5",
2332
+ timestamp: "#949ba4",
2333
+ reactionBg: "#2b2d31",
2334
+ reactionBorder: "#3f4147",
2335
+ reactionText: "#dbdee1",
2336
+ composerBg: "#383a40",
2337
+ placeholder: "#6d7079",
2338
+ mentionText: "#c9cdfb",
2339
+ mentionBg: "rgba(88,101,242,0.3)",
2340
+ codeBg: "#2b2d31",
2341
+ codeText: "#dbdee1",
2342
+ link: "#00a8fc",
2343
+ hashtag: "#80848e"
2344
+ };
2345
+ var DISCORD_FONT_STACK = '"gg sans", "Noto Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
2346
+ var GUTTER = 56;
2347
+ function formatTime3(atMs) {
2348
+ const base = 9 * 3600 * 1e3;
2349
+ const total = Math.floor((base + atMs) / 1e3);
2350
+ const h = Math.floor(total / 3600) % 24;
2351
+ const m = Math.floor(total % 3600 / 60);
2352
+ const ampm = h >= 12 ? "PM" : "AM";
2353
+ const hr = h % 12 === 0 ? 12 : h % 12;
2354
+ return `Today at ${hr}:${String(m).padStart(2, "0")} ${ampm}`;
2355
+ }
2356
+ function initials5(name) {
2357
+ return name.split(/\s+/).map((w) => w.charAt(0)).slice(0, 2).join("").toUpperCase();
2358
+ }
2359
+ var markStyles4 = {
2360
+ link: { color: DISCORD.link, textDecoration: "none" },
2361
+ mention: {
2362
+ color: DISCORD.mentionText,
2363
+ background: DISCORD.mentionBg,
2364
+ borderRadius: 3,
2365
+ padding: "0 2px",
2366
+ fontWeight: 500
2367
+ },
2368
+ code: {
2369
+ fontFamily: "Menlo, Consolas, monospace",
2370
+ fontSize: "0.85em",
2371
+ background: DISCORD.codeBg,
2372
+ color: DISCORD.codeText,
2373
+ borderRadius: 3,
2374
+ padding: "1px 4px"
2375
+ }
2376
+ };
2377
+ var Avatar6 = ({ participant, size = 40 }) => {
2378
+ if (participant.avatar) {
2379
+ return /* @__PURE__ */ jsx(
2380
+ "img",
2381
+ {
2382
+ src: participant.avatar,
2383
+ alt: participant.name,
2384
+ width: size,
2385
+ height: size,
2386
+ style: {
2387
+ width: size,
2388
+ height: size,
2389
+ borderRadius: "50%",
2390
+ objectFit: "cover"
2391
+ }
2392
+ }
2393
+ );
2394
+ }
2395
+ return /* @__PURE__ */ jsx(
2396
+ "div",
2397
+ {
2398
+ style: {
2399
+ width: size,
2400
+ height: size,
2401
+ borderRadius: "50%",
2402
+ background: participant.color ?? "#5865f2",
2403
+ color: "#fff",
2404
+ display: "flex",
2405
+ alignItems: "center",
2406
+ justifyContent: "center",
2407
+ fontSize: size * 0.4,
2408
+ fontWeight: 500
2409
+ },
2410
+ children: initials5(participant.name)
2411
+ }
2412
+ );
2413
+ };
2414
+ var Reaction6 = ({ reaction }) => /* @__PURE__ */ jsxs(
2415
+ "span",
2416
+ {
2417
+ style: {
2418
+ ...popIn(reaction.progress),
2419
+ display: "inline-flex",
2420
+ alignItems: "center",
2421
+ gap: 5,
2422
+ background: DISCORD.reactionBg,
2423
+ border: `1px solid ${DISCORD.reactionBorder}`,
2424
+ borderRadius: 8,
2425
+ padding: "2px 7px",
2426
+ fontSize: 13,
2427
+ color: DISCORD.reactionText
2428
+ },
2429
+ children: [
2430
+ /* @__PURE__ */ jsx("span", { children: reaction.emoji }),
2431
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: 12 }, children: reaction.count })
2432
+ ]
2433
+ }
2434
+ );
2435
+ var Message6 = ({ message, author }) => {
2436
+ const roleColor = author.color ?? DISCORD.username;
2437
+ const body = /* @__PURE__ */ jsxs("div", { style: { color: DISCORD.text, fontSize: 15, lineHeight: 1.375 }, children: [
2438
+ /* @__PURE__ */ jsx(
2439
+ MessageContent,
2440
+ {
2441
+ nodes: message.content,
2442
+ styles: markStyles4,
2443
+ imageStyle: { borderRadius: 8, marginTop: 4, maxWidth: 320 }
2444
+ }
2445
+ ),
2446
+ message.reactions.length > 0 ? /* @__PURE__ */ jsx(
2447
+ "div",
2448
+ {
2449
+ style: { display: "flex", gap: 4, marginTop: 5, flexWrap: "wrap" },
2450
+ children: message.reactions.map((r, i) => /* @__PURE__ */ jsx(Reaction6, { theme: "dark", reaction: r }, i))
2451
+ }
2452
+ ) : null
2453
+ ] });
2454
+ if (message.isGrouped) {
2455
+ return /* @__PURE__ */ jsx(
2456
+ "div",
2457
+ {
2458
+ style: {
2459
+ padding: `1px 16px 1px ${GUTTER}px`,
2460
+ ...fadeSlideIn(message.revealProgress, { distance: 4 })
2461
+ },
2462
+ children: body
2463
+ }
2464
+ );
2465
+ }
2466
+ return /* @__PURE__ */ jsxs(
2467
+ "div",
2468
+ {
2469
+ style: {
2470
+ display: "flex",
2471
+ gap: 16,
2472
+ padding: "8px 16px 2px",
2473
+ ...fadeSlideIn(message.revealProgress, { distance: 4 })
2474
+ },
2475
+ children: [
2476
+ /* @__PURE__ */ jsx(Avatar6, { theme: "dark", participant: author, size: 40 }),
2477
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
2478
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 8 }, children: [
2479
+ /* @__PURE__ */ jsx("span", { style: { color: roleColor, fontWeight: 500, fontSize: 15 }, children: author.name }),
2480
+ /* @__PURE__ */ jsx("span", { style: { color: DISCORD.timestamp, fontSize: 12 }, children: formatTime3(message.atMs) })
2481
+ ] }),
2482
+ body
2483
+ ] })
2484
+ ]
2485
+ }
2486
+ );
2487
+ };
2488
+ var SystemMessage6 = ({ message }) => {
2489
+ const text = message.content.map(
2490
+ (n) => n.type === "text" ? n.spans.map((s) => s.value ?? "").join("") : ""
2491
+ ).join(" ");
2492
+ return /* @__PURE__ */ jsxs(
2493
+ "div",
2494
+ {
2495
+ style: {
2496
+ display: "flex",
2497
+ gap: 16,
2498
+ alignItems: "center",
2499
+ padding: "4px 16px 4px 24px",
2500
+ color: DISCORD.muted,
2501
+ fontSize: 14,
2502
+ ...fadeSlideIn(message.revealProgress, { distance: 0 })
2503
+ },
2504
+ children: [
2505
+ /* @__PURE__ */ jsx("span", { style: { color: "#3ba55c" }, children: "\uFF0B" }),
2506
+ text
2507
+ ]
2508
+ }
2509
+ );
2510
+ };
2511
+ var TypingIndicator6 = ({ typing, author }) => /* @__PURE__ */ jsxs(
2512
+ "div",
2513
+ {
2514
+ style: {
2515
+ display: "flex",
2516
+ alignItems: "center",
2517
+ gap: 8,
2518
+ padding: "2px 16px 4px",
2519
+ color: DISCORD.text,
2520
+ fontSize: 13
2521
+ },
2522
+ children: [
2523
+ /* @__PURE__ */ jsx(TypingDots, { progress: typing.progress, color: DISCORD.muted, size: 5 }),
2524
+ /* @__PURE__ */ jsxs("span", { children: [
2525
+ /* @__PURE__ */ jsx("strong", { children: author.name }),
2526
+ " is typing\u2026"
2527
+ ] })
2528
+ ]
2529
+ }
2530
+ );
2531
+ var Composer6 = ({ composer }) => {
2532
+ const hasText = composer.text.length > 0;
2533
+ return /* @__PURE__ */ jsx("div", { style: { flex: "0 0 auto", padding: "0 16px 18px" }, children: /* @__PURE__ */ jsxs(
2534
+ "div",
2535
+ {
2536
+ style: {
2537
+ background: DISCORD.composerBg,
2538
+ borderRadius: 8,
2539
+ padding: "11px 14px",
2540
+ color: DISCORD.text,
2541
+ fontSize: 15,
2542
+ display: "flex",
2543
+ alignItems: "center",
2544
+ gap: 12
2545
+ },
2546
+ children: [
2547
+ /* @__PURE__ */ jsx("span", { style: { color: DISCORD.muted, fontSize: 20 }, children: "\uFF0B" }),
2548
+ hasText ? /* @__PURE__ */ jsxs("span", { children: [
2549
+ composer.text,
2550
+ /* @__PURE__ */ jsx("span", { style: { color: DISCORD.text }, children: "|" })
2551
+ ] }) : /* @__PURE__ */ jsx("span", { style: { color: DISCORD.placeholder }, children: "Message #general" })
2552
+ ]
2553
+ }
2554
+ ) });
2555
+ };
2556
+ var Frame7 = ({
2557
+ options,
2558
+ children
2559
+ }) => {
2560
+ const channel = typeof options?.channel === "string" ? options.channel : "general";
2561
+ return /* @__PURE__ */ jsxs(
2562
+ "div",
2563
+ {
2564
+ style: {
2565
+ fontFamily: DISCORD_FONT_STACK,
2566
+ background: DISCORD.bg,
2567
+ color: DISCORD.text,
2568
+ display: "flex",
2569
+ flexDirection: "column",
2570
+ height: "100%",
2571
+ width: "100%",
2572
+ WebkitFontSmoothing: "antialiased"
2573
+ },
2574
+ children: [
2575
+ /* @__PURE__ */ jsxs(
2576
+ "div",
2577
+ {
2578
+ style: {
2579
+ flex: "0 0 auto",
2580
+ display: "flex",
2581
+ alignItems: "center",
2582
+ gap: 8,
2583
+ padding: "12px 16px",
2584
+ borderBottom: `1px solid ${DISCORD.channelBarBorder}`,
2585
+ boxShadow: "0 1px 0 rgba(0,0,0,0.2)"
2586
+ },
2587
+ children: [
2588
+ /* @__PURE__ */ jsx("span", { style: { color: DISCORD.hashtag, fontSize: 22, fontWeight: 600 }, children: "#" }),
2589
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: 16, color: "#f2f3f5" }, children: channel })
2590
+ ]
2591
+ }
2592
+ ),
2593
+ /* @__PURE__ */ jsx(
2594
+ "div",
2595
+ {
2596
+ style: {
2597
+ flex: "1 1 auto",
2598
+ minHeight: 0,
2599
+ display: "flex",
2600
+ flexDirection: "column",
2601
+ justifyContent: "flex-end",
2602
+ overflow: "hidden",
2603
+ paddingBottom: 6
2604
+ },
2605
+ children
2606
+ }
2607
+ )
2608
+ ]
2609
+ }
2610
+ );
2611
+ };
2612
+ var discordComponents = {
2613
+ Frame: Frame7,
2614
+ Message: Message6,
2615
+ TypingIndicator: TypingIndicator6,
2616
+ Reaction: Reaction6,
2617
+ Composer: Composer6,
2618
+ SystemMessage: SystemMessage6,
2619
+ Avatar: Avatar6
2620
+ };
2621
+
2622
+ // src/discord/index.ts
2623
+ var discordCapabilities = {
2624
+ events: {
2625
+ message: "native",
2626
+ composerType: "native",
2627
+ send: "native",
2628
+ typing: "native",
2629
+ reaction: "native",
2630
+ system: "native",
2631
+ edit: "native",
2632
+ delete: "native",
2633
+ readReceipt: "unsupported",
2634
+ beat: "native"
2635
+ },
2636
+ content: { text: true, image: true },
2637
+ reactions: true,
2638
+ threads: true,
2639
+ readReceipts: false
2640
+ };
2641
+ var discordOptionsSchema = z.object({
2642
+ /** Channel name (rendered after the `#`). */
2643
+ channel: z.string().optional()
2644
+ });
2645
+ var discord = defineSkin({
2646
+ id: "discord",
2647
+ meta: {
2648
+ name: "Discord",
2649
+ defaultCanvas: { width: 600, height: 480 },
2650
+ supportsThemes: ["dark"],
2651
+ capabilities: discordCapabilities,
2652
+ optionsSchema: discordOptionsSchema
2653
+ },
2654
+ components: discordComponents
2655
+ });
2656
+
2657
+ // src/registry.ts
2658
+ var builtinSkins = {
2659
+ slack,
2660
+ "claude-code": claudeCode,
2661
+ imessage,
2662
+ whatsapp,
2663
+ cursor,
2664
+ "messages-macos": messagesMacos,
2665
+ discord
2666
+ };
2667
+ function getSkin(id) {
2668
+ return builtinSkins[id];
2669
+ }
2670
+
2671
+ export { SLACK_COLORS, builtinSkins, claudeCode, cursor, discord, getSkin, imessage, messagesMacos, slack, whatsapp };
2672
+ //# sourceMappingURL=index.js.map
2673
+ //# sourceMappingURL=index.js.map