@runtypelabs/persona 4.13.0 → 4.15.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.
Files changed (106) hide show
  1. package/README.md +4 -4
  2. package/dist/animations/glyph-cycle.d.cts +1 -1
  3. package/dist/animations/glyph-cycle.d.ts +1 -1
  4. package/dist/animations/{types-DveIaNx6.d.cts → types-BpWGm7_6.d.cts} +17 -0
  5. package/dist/animations/{types-DveIaNx6.d.ts → types-BpWGm7_6.d.ts} +17 -0
  6. package/dist/animations/wipe.d.cts +1 -1
  7. package/dist/animations/wipe.d.ts +1 -1
  8. package/dist/chunk-QJ4LV2KW.js +1 -0
  9. package/dist/codegen.cjs +12 -11
  10. package/dist/codegen.js +14 -13
  11. package/dist/{context-mentions-ONG7A7M6.js → context-mentions-BTSTIBFC.js} +1 -1
  12. package/dist/context-mentions.cjs +11 -8
  13. package/dist/context-mentions.d.cts +339 -22
  14. package/dist/context-mentions.d.ts +339 -22
  15. package/dist/context-mentions.js +11 -8
  16. package/dist/index.cjs +68 -67
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +483 -48
  19. package/dist/index.d.ts +483 -48
  20. package/dist/index.global.js +61 -58
  21. package/dist/index.global.js.map +1 -1
  22. package/dist/index.js +70 -69
  23. package/dist/index.js.map +1 -1
  24. package/dist/launcher.global.js +5 -2
  25. package/dist/launcher.global.js.map +1 -1
  26. package/dist/smart-dom-reader.d.cts +339 -22
  27. package/dist/smart-dom-reader.d.ts +339 -22
  28. package/dist/theme-editor-preview.cjs +67 -67
  29. package/dist/theme-editor-preview.d.cts +355 -23
  30. package/dist/theme-editor-preview.d.ts +355 -23
  31. package/dist/theme-editor-preview.js +75 -75
  32. package/dist/theme-editor.cjs +10 -10
  33. package/dist/theme-editor.d.cts +376 -24
  34. package/dist/theme-editor.d.ts +376 -24
  35. package/dist/theme-editor.js +10 -10
  36. package/dist/theme-reference.cjs +1 -1
  37. package/dist/theme-reference.d.cts +38 -0
  38. package/dist/theme-reference.d.ts +38 -0
  39. package/dist/theme-reference.js +1 -1
  40. package/dist/widget.css +1 -1
  41. package/package.json +1 -1
  42. package/src/artifacts-session.test.ts +106 -0
  43. package/src/ask-user-question-tool.ts +10 -7
  44. package/src/client.test.ts +2 -2
  45. package/src/client.ts +4 -1
  46. package/src/components/artifact-card.ts +13 -2
  47. package/src/components/artifact-inline.ts +11 -2
  48. package/src/components/artifact-preview.ts +1 -1
  49. package/src/components/composer-builder.test.ts +2 -0
  50. package/src/components/composer-builder.ts +1 -1
  51. package/src/components/composer-parts.test.ts +105 -4
  52. package/src/components/composer-parts.ts +54 -16
  53. package/src/components/message-bubble.test.ts +7 -1
  54. package/src/components/message-bubble.ts +11 -8
  55. package/src/components/messages.ts +5 -2
  56. package/src/components/panel.ts +31 -5
  57. package/src/components/pill-composer-builder.test.ts +18 -0
  58. package/src/components/suggestions.test.ts +233 -0
  59. package/src/components/suggestions.ts +463 -81
  60. package/src/components/widget-view.ts +4 -0
  61. package/src/defaults.ts +5 -3
  62. package/src/generated/runtype-openapi-contract.ts +17 -0
  63. package/src/index-core.ts +52 -2
  64. package/src/launcher-global.ts +1 -1
  65. package/src/plugins/types.ts +71 -3
  66. package/src/presets.ts +3 -3
  67. package/src/session.ts +55 -12
  68. package/src/styles/widget-styles.test.ts +162 -0
  69. package/src/styles/widget.css +440 -1
  70. package/src/suggest-replies-tool.test.ts +233 -2
  71. package/src/suggest-replies-tool.ts +115 -39
  72. package/src/theme-editor/index.ts +5 -0
  73. package/src/theme-editor/presets.test.ts +43 -0
  74. package/src/theme-editor/presets.ts +101 -87
  75. package/src/theme-editor/preview-utils.test.ts +34 -0
  76. package/src/theme-editor/preview-utils.ts +77 -2
  77. package/src/theme-editor/sections.test.ts +72 -7
  78. package/src/theme-editor/sections.ts +113 -13
  79. package/src/theme-editor/state-preferences.test.ts +15 -0
  80. package/src/theme-editor/state.ts +46 -0
  81. package/src/theme-editor/types.ts +15 -1
  82. package/src/theme-editor/webmcp/tools.test.ts +13 -0
  83. package/src/theme-editor/webmcp/tools.ts +5 -0
  84. package/src/theme-reference.ts +9 -2
  85. package/src/types/theme.ts +32 -0
  86. package/src/types.ts +291 -25
  87. package/src/ui.artifact-pane-gating.test.ts +5 -5
  88. package/src/ui.config-preferences.test.ts +166 -0
  89. package/src/ui.detached-panel.test.ts +1 -1
  90. package/src/ui.suggest-replies.test.ts +1066 -1
  91. package/src/ui.ts +311 -45
  92. package/src/ui.typing-indicator.test.ts +135 -0
  93. package/src/utils/artifact-display.test.ts +180 -16
  94. package/src/utils/artifact-display.ts +155 -14
  95. package/src/utils/artifact-file.test.ts +1 -1
  96. package/src/utils/code-generators.test.ts +40 -0
  97. package/src/utils/code-generators.ts +22 -0
  98. package/src/utils/config-merge.test.ts +84 -0
  99. package/src/utils/config-merge.ts +6 -1
  100. package/src/utils/feature-preferences.test.ts +326 -0
  101. package/src/utils/feature-preferences.ts +498 -0
  102. package/src/utils/icons.test.ts +26 -0
  103. package/src/utils/icons.ts +8 -0
  104. package/src/utils/theme.test.ts +171 -0
  105. package/src/utils/tokens.ts +71 -7
  106. package/dist/chunk-MMUPR2JW.js +0 -1
@@ -236,6 +236,418 @@
236
236
  border-radius: var(--persona-button-radius);
237
237
  }
238
238
 
239
+ /* Suggestions ----------------------------------------------------------- */
240
+
241
+ .persona-suggestions {
242
+ --persona-suggestion-icon-size: var(
243
+ --persona-components-suggestion-chip-iconSize,
244
+ 16px
245
+ );
246
+ display: flex;
247
+ align-items: stretch;
248
+ flex-shrink: 0;
249
+ gap: 8px;
250
+ min-width: 0;
251
+ }
252
+
253
+ .persona-suggestions[hidden] {
254
+ display: none !important;
255
+ }
256
+
257
+ .persona-suggestions[data-persona-suggestion-surface="starter"] {
258
+ margin-top: 16px;
259
+ }
260
+
261
+ [data-persona-suggestions="follow-up"] {
262
+ /* The transcript body uses a roomy 24px section gap; pull contextual
263
+ follow-ups closer to the answer they belong to. */
264
+ margin-top: -12px;
265
+ }
266
+
267
+ .persona-suggestions[data-variant="card"] {
268
+ --persona-suggestion-icon-size: var(
269
+ --persona-components-suggestion-card-iconSize,
270
+ 18px
271
+ );
272
+ display: grid;
273
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
274
+ }
275
+
276
+ /* Welcome-surface policy, not a card property: the cap keeps a wide inline
277
+ panel at two starter columns instead of one stretched row. */
278
+ .persona-suggestions[data-variant="card"][data-persona-suggestion-surface="starter"] {
279
+ max-width: 600px;
280
+ }
281
+
282
+ .persona-suggestions[data-variant="list"] {
283
+ --persona-suggestion-icon-size: var(
284
+ --persona-components-suggestion-list-iconSize,
285
+ 17px
286
+ );
287
+ flex-direction: column;
288
+ }
289
+
290
+ .persona-suggestions[data-variant="chip"][data-overflow="scroll"] {
291
+ --persona-suggestion-scroll-fade-size: 32px;
292
+ flex-wrap: nowrap;
293
+ overflow-x: auto;
294
+ overscroll-behavior-inline: contain;
295
+ scrollbar-width: thin;
296
+ scroll-snap-type: inline proximity;
297
+ padding: 2px;
298
+ }
299
+
300
+ .persona-suggestions[data-variant="chip"][data-overflow="scroll"][data-scroll-right]:not(
301
+ [data-scroll-left]
302
+ ) {
303
+ -webkit-mask-image: linear-gradient(
304
+ to right,
305
+ #000 0,
306
+ #000 calc(100% - var(--persona-suggestion-scroll-fade-size)),
307
+ transparent 100%
308
+ );
309
+ mask-image: linear-gradient(
310
+ to right,
311
+ #000 0,
312
+ #000 calc(100% - var(--persona-suggestion-scroll-fade-size)),
313
+ transparent 100%
314
+ );
315
+ }
316
+
317
+ .persona-suggestions[data-variant="chip"][data-overflow="scroll"][data-scroll-left]:not(
318
+ [data-scroll-right]
319
+ ) {
320
+ -webkit-mask-image: linear-gradient(
321
+ to right,
322
+ transparent 0,
323
+ #000 var(--persona-suggestion-scroll-fade-size),
324
+ #000 100%
325
+ );
326
+ mask-image: linear-gradient(
327
+ to right,
328
+ transparent 0,
329
+ #000 var(--persona-suggestion-scroll-fade-size),
330
+ #000 100%
331
+ );
332
+ }
333
+
334
+ .persona-suggestions[data-variant="chip"][data-overflow="scroll"][data-scroll-left][data-scroll-right] {
335
+ -webkit-mask-image: linear-gradient(
336
+ to right,
337
+ transparent 0,
338
+ #000 var(--persona-suggestion-scroll-fade-size),
339
+ #000 calc(100% - var(--persona-suggestion-scroll-fade-size)),
340
+ transparent 100%
341
+ );
342
+ mask-image: linear-gradient(
343
+ to right,
344
+ transparent 0,
345
+ #000 var(--persona-suggestion-scroll-fade-size),
346
+ #000 calc(100% - var(--persona-suggestion-scroll-fade-size)),
347
+ transparent 100%
348
+ );
349
+ }
350
+
351
+ .persona-suggestions[data-variant="chip"][data-overflow="wrap"] {
352
+ flex-wrap: wrap;
353
+ }
354
+
355
+ .persona-suggestion {
356
+ appearance: none;
357
+ display: flex;
358
+ align-items: center;
359
+ justify-content: flex-start;
360
+ min-width: 0;
361
+ text-align: left;
362
+ font-family: inherit;
363
+ font-weight: 500;
364
+ cursor: pointer;
365
+ transition:
366
+ background-color 140ms ease,
367
+ border-color 140ms ease,
368
+ color 140ms ease,
369
+ box-shadow 140ms ease,
370
+ transform 100ms ease;
371
+ }
372
+
373
+ .persona-suggestion--chip {
374
+ flex: 0 0 auto;
375
+ scroll-snap-align: start;
376
+ min-height: var(--persona-components-suggestion-chip-minHeight, 36px);
377
+ gap: var(--persona-components-suggestion-chip-gap, 0.5rem);
378
+ padding: var(
379
+ --persona-components-suggestion-chip-padding,
380
+ 0.5rem 0.875rem
381
+ );
382
+ border: 1px solid
383
+ var(--persona-components-suggestion-chip-border, var(--persona-border));
384
+ border-radius: var(
385
+ --persona-components-suggestion-chip-borderRadius,
386
+ 9999px
387
+ );
388
+ background: var(
389
+ --persona-components-suggestion-chip-background,
390
+ var(--persona-surface)
391
+ );
392
+ color: var(
393
+ --persona-components-suggestion-chip-foreground,
394
+ var(--persona-text)
395
+ );
396
+ font-size: var(--persona-components-suggestion-chip-fontSize, 0.8125rem);
397
+ line-height: var(--persona-components-suggestion-chip-lineHeight, 1.25);
398
+ }
399
+
400
+ .persona-suggestion--card {
401
+ align-items: flex-start;
402
+ min-height: var(--persona-components-suggestion-card-minHeight, 72px);
403
+ gap: var(--persona-components-suggestion-card-gap, 0.625rem);
404
+ padding: var(--persona-components-suggestion-card-padding, 1rem);
405
+ border: 1px solid
406
+ var(--persona-components-suggestion-card-border, var(--persona-border));
407
+ border-radius: var(
408
+ --persona-components-suggestion-card-borderRadius,
409
+ var(--persona-radius-xl)
410
+ );
411
+ background: var(
412
+ --persona-components-suggestion-card-background,
413
+ var(--persona-surface)
414
+ );
415
+ color: var(
416
+ --persona-components-suggestion-card-foreground,
417
+ var(--persona-text)
418
+ );
419
+ box-shadow: var(--persona-components-suggestion-card-shadow, none);
420
+ font-size: var(--persona-components-suggestion-card-fontSize, 0.875rem);
421
+ line-height: var(--persona-components-suggestion-card-lineHeight, 1.35);
422
+ }
423
+
424
+ .persona-suggestion--list {
425
+ align-items: flex-start;
426
+ width: 100%;
427
+ min-height: var(--persona-components-suggestion-list-minHeight, 44px);
428
+ gap: var(--persona-components-suggestion-list-gap, 0.625rem);
429
+ padding: var(--persona-components-suggestion-list-padding, 0.75rem);
430
+ border: 1px solid
431
+ var(--persona-components-suggestion-list-border, var(--persona-border));
432
+ border-radius: var(
433
+ --persona-components-suggestion-list-borderRadius,
434
+ var(--persona-radius-md)
435
+ );
436
+ background: var(
437
+ --persona-components-suggestion-list-background,
438
+ transparent
439
+ );
440
+ color: var(
441
+ --persona-components-suggestion-list-foreground,
442
+ var(--persona-text)
443
+ );
444
+ font-size: var(--persona-components-suggestion-list-fontSize, 0.875rem);
445
+ line-height: var(--persona-components-suggestion-list-lineHeight, 1.35);
446
+ }
447
+
448
+ .persona-suggestion__icon,
449
+ .persona-suggestion__arrow {
450
+ flex: 0 0 auto;
451
+ }
452
+
453
+ /* The taller viewport box centers the graphic on the label's first line box;
454
+ the icon keeps its size because the width constraint drives `meet` scaling. */
455
+ .persona-suggestion--card .persona-suggestion__icon {
456
+ block-size: calc(
457
+ 1em * var(--persona-components-suggestion-card-lineHeight, 1.35)
458
+ );
459
+ }
460
+
461
+ .persona-suggestion--list .persona-suggestion__icon {
462
+ block-size: calc(
463
+ 1em * var(--persona-components-suggestion-list-lineHeight, 1.35)
464
+ );
465
+ }
466
+
467
+ .persona-suggestion__copy {
468
+ display: flex;
469
+ flex: 1 1 auto;
470
+ min-width: 0;
471
+ flex-direction: column;
472
+ gap: 3px;
473
+ }
474
+
475
+ .persona-suggestion__label {
476
+ overflow-wrap: anywhere;
477
+ }
478
+
479
+ .persona-suggestion__description {
480
+ color: var(--persona-text-muted);
481
+ font-size: 0.75rem;
482
+ font-weight: 400;
483
+ line-height: 1.35;
484
+ }
485
+
486
+ /* Hover-revealed: the arrow is an affordance hint, not standing decoration. */
487
+ .persona-suggestion__arrow {
488
+ margin-left: auto;
489
+ opacity: 0;
490
+ transition: opacity 140ms ease;
491
+ }
492
+
493
+ .persona-suggestion:focus-visible .persona-suggestion__arrow {
494
+ opacity: 0.55;
495
+ }
496
+
497
+ /* Quiet accent, never a solid fill: an emphasized item reads as a sibling of
498
+ the set rather than a CTA among ghost buttons. */
499
+ .persona-suggestion[data-emphasis="primary"] {
500
+ border-color: var(--persona-primary);
501
+ background: transparent;
502
+ background: color-mix(in srgb, var(--persona-primary) 6%, transparent);
503
+ }
504
+
505
+ .persona-suggestion[data-emphasis="primary"] .persona-suggestion__icon {
506
+ color: var(--persona-primary);
507
+ }
508
+
509
+ @media (hover: hover) {
510
+ .persona-suggestion--chip:hover {
511
+ border-color: var(
512
+ --persona-components-suggestion-chip-hoverBorder,
513
+ var(--persona-border)
514
+ );
515
+ background: var(
516
+ --persona-components-suggestion-chip-hoverBackground,
517
+ var(--persona-container)
518
+ );
519
+ color: var(
520
+ --persona-components-suggestion-chip-hoverForeground,
521
+ inherit
522
+ );
523
+ }
524
+
525
+ .persona-suggestion:hover .persona-suggestion__arrow {
526
+ opacity: 0.55;
527
+ }
528
+
529
+ .persona-suggestion--card:hover {
530
+ border-color: var(
531
+ --persona-components-suggestion-card-hoverBorder,
532
+ var(--persona-border)
533
+ );
534
+ background: var(
535
+ --persona-components-suggestion-card-hoverBackground,
536
+ var(--persona-container)
537
+ );
538
+ box-shadow: var(--persona-shadow-sm);
539
+ transform: translateY(-1px);
540
+ }
541
+
542
+ .persona-suggestion--list:hover {
543
+ border-color: var(
544
+ --persona-components-suggestion-list-hoverBorder,
545
+ var(--persona-border)
546
+ );
547
+ background: var(
548
+ --persona-components-suggestion-list-hoverBackground,
549
+ var(--persona-container)
550
+ );
551
+ }
552
+
553
+ .persona-suggestion[data-emphasis="primary"]:hover {
554
+ border-color: var(--persona-primary);
555
+ background: transparent;
556
+ background: color-mix(in srgb, var(--persona-primary) 12%, transparent);
557
+ }
558
+ }
559
+
560
+ .persona-suggestion:focus-visible {
561
+ outline: 2px solid
562
+ var(
563
+ --persona-components-suggestion-chip-focusRing,
564
+ var(--persona-accent)
565
+ );
566
+ outline-offset: 2px;
567
+ }
568
+
569
+ .persona-suggestion--card:focus-visible {
570
+ outline-color: var(
571
+ --persona-components-suggestion-card-focusRing,
572
+ var(--persona-accent)
573
+ );
574
+ }
575
+
576
+ .persona-suggestion--list:focus-visible {
577
+ outline-color: var(
578
+ --persona-components-suggestion-list-focusRing,
579
+ var(--persona-accent)
580
+ );
581
+ }
582
+
583
+ .persona-suggestion--chip:active {
584
+ background: var(
585
+ --persona-components-suggestion-chip-pressedBackground,
586
+ var(--persona-container)
587
+ );
588
+ transform: scale(0.98);
589
+ }
590
+
591
+ .persona-suggestion--card:active {
592
+ background: var(
593
+ --persona-components-suggestion-card-pressedBackground,
594
+ var(--persona-container)
595
+ );
596
+ transform: translateY(1px);
597
+ }
598
+
599
+ .persona-suggestion--list:active {
600
+ background: var(
601
+ --persona-components-suggestion-list-pressedBackground,
602
+ var(--persona-container)
603
+ );
604
+ }
605
+
606
+ .persona-suggestion[data-emphasis="primary"]:active {
607
+ background: transparent;
608
+ background: color-mix(in srgb, var(--persona-primary) 16%, transparent);
609
+ }
610
+
611
+ .persona-suggestion:disabled {
612
+ cursor: not-allowed;
613
+ opacity: var(
614
+ --persona-components-suggestion-chip-disabledOpacity,
615
+ 0.5
616
+ );
617
+ }
618
+
619
+ .persona-suggestion--card:disabled {
620
+ opacity: var(
621
+ --persona-components-suggestion-card-disabledOpacity,
622
+ 0.5
623
+ );
624
+ }
625
+
626
+ .persona-suggestion--list:disabled {
627
+ opacity: var(
628
+ --persona-components-suggestion-list-disabledOpacity,
629
+ 0.5
630
+ );
631
+ }
632
+
633
+ @media (pointer: coarse) {
634
+ .persona-suggestion {
635
+ min-height: 44px;
636
+ }
637
+
638
+ /* No hover to reveal it, so the arrow would be permanent decoration. */
639
+ .persona-suggestion__arrow {
640
+ display: none;
641
+ }
642
+ }
643
+
644
+ @media (prefers-reduced-motion: reduce) {
645
+ .persona-suggestion,
646
+ .persona-suggestion__arrow {
647
+ transition: none;
648
+ }
649
+ }
650
+
239
651
  /* Composer ghost icon buttons (attachment + mention): transparent, neutral
240
652
  foreground, subtle hover. Themeable via `components.button.ghost.*`
241
653
  → `--persona-button-ghost-*`. The `[data-persona-root]` prefix outranks the
@@ -294,6 +706,10 @@
294
706
  color: var(--persona-primary, #171717);
295
707
  }
296
708
 
709
+ .persona-text-persona-text {
710
+ color: var(--persona-text, #111827);
711
+ }
712
+
297
713
  .persona-text-persona-call-to-action {
298
714
  color: var(--persona-call-to-action, var(--persona-text-inverse, #ffffff));
299
715
  }
@@ -930,6 +1346,11 @@
930
1346
  box-shadow: none !important;
931
1347
  }
932
1348
 
1349
+ .persona-composer-textarea::placeholder {
1350
+ color: var(--persona-input-placeholder, var(--persona-text-muted, #9ca3af));
1351
+ opacity: 1;
1352
+ }
1353
+
933
1354
  /* Prevent iOS Safari from zooming on input focus (requires 16px minimum) */
934
1355
  @media (hover: none) and (pointer: coarse) {
935
1356
  .persona-composer-textarea {
@@ -981,6 +1402,24 @@
981
1402
  box-shadow: var(--persona-composer-shadow, none);
982
1403
  }
983
1404
 
1405
+ /* Composer spacing, themeable via `components.composer.padding` / `.gap`.
1406
+ The `[data-persona-root]` prefix outranks the `persona-px-4 persona-py-3
1407
+ persona-gap-2` utilities the form still carries; the fallbacks reproduce
1408
+ them exactly. The pill composer is excluded because it sets its own
1409
+ grid padding/gap (see `.persona-pill-composer`). */
1410
+ [data-persona-root] .persona-widget-composer:not(.persona-pill-composer) {
1411
+ padding: var(--persona-composer-padding, 0.75rem 1rem);
1412
+ gap: var(--persona-composer-gap, 0.5rem);
1413
+ }
1414
+
1415
+ /* Composer type scale, themeable via `components.composer.fontSize` /
1416
+ `.lineHeight`. Outranks the `persona-text-sm` utility on the textarea;
1417
+ fallbacks match it. Applies to the pill composer's textarea too. */
1418
+ [data-persona-root] .persona-composer-textarea {
1419
+ font-size: var(--persona-composer-font-size, 0.875rem);
1420
+ line-height: var(--persona-composer-line-height, 1.25rem);
1421
+ }
1422
+
984
1423
  .persona-form-grid {
985
1424
  display: flex;
986
1425
  flex-direction: column;
@@ -4928,7 +5367,7 @@
4928
5367
 
4929
5368
  .persona-composer-contenteditable:empty::before {
4930
5369
  content: attr(data-placeholder);
4931
- color: var(--persona-placeholder, var(--persona-muted, #9ca3af));
5370
+ color: var(--persona-input-placeholder, var(--persona-text-muted, #9ca3af));
4932
5371
  pointer-events: none;
4933
5372
  }
4934
5373