@runtypelabs/persona 4.6.1 → 4.8.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 (120) hide show
  1. package/dist/animations/glyph-cycle.cjs +2 -2
  2. package/dist/animations/glyph-cycle.d.cts +1 -1
  3. package/dist/animations/glyph-cycle.d.ts +1 -1
  4. package/dist/animations/glyph-cycle.js +2 -2
  5. package/dist/animations/{types-CSmiKRVa.d.cts → types-BsZtXPKK.d.cts} +43 -3
  6. package/dist/animations/{types-CSmiKRVa.d.ts → types-BsZtXPKK.d.ts} +43 -3
  7. package/dist/animations/wipe.cjs +2 -2
  8. package/dist/animations/wipe.d.cts +1 -1
  9. package/dist/animations/wipe.d.ts +1 -1
  10. package/dist/chunk-5EIIHQLQ.js +1 -0
  11. package/dist/codegen.cjs +12 -12
  12. package/dist/codegen.js +14 -14
  13. package/dist/index.cjs +91 -68
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +918 -174
  16. package/dist/index.d.ts +918 -174
  17. package/dist/index.global.js +81 -57
  18. package/dist/index.global.js.map +1 -1
  19. package/dist/index.js +89 -66
  20. package/dist/index.js.map +1 -1
  21. package/dist/install.global.js +1 -1
  22. package/dist/install.global.js.map +1 -1
  23. package/dist/launcher.global.js +3 -2
  24. package/dist/launcher.global.js.map +1 -1
  25. package/dist/markdown-parsers.js +24 -24
  26. package/dist/plugin-kit.cjs +1 -1
  27. package/dist/plugin-kit.js +1 -1
  28. package/dist/runtype-tts-entry-UJAEF7NZ.js +1 -0
  29. package/dist/runtype-tts.js +1 -1
  30. package/dist/session-reconnect-JKIJBHS5.js +1 -0
  31. package/dist/smart-dom-reader.cjs +17 -17
  32. package/dist/smart-dom-reader.d.cts +753 -15
  33. package/dist/smart-dom-reader.d.ts +753 -15
  34. package/dist/smart-dom-reader.js +17 -17
  35. package/dist/testing.cjs +3 -3
  36. package/dist/testing.js +3 -3
  37. package/dist/theme-editor-preview.cjs +81 -58
  38. package/dist/theme-editor-preview.d.cts +761 -15
  39. package/dist/theme-editor-preview.d.ts +761 -15
  40. package/dist/theme-editor-preview.js +81 -58
  41. package/dist/theme-editor.cjs +6 -6
  42. package/dist/theme-editor.d.cts +753 -15
  43. package/dist/theme-editor.d.ts +753 -15
  44. package/dist/theme-editor.js +10 -10
  45. package/dist/theme-reference.cjs +1 -1
  46. package/dist/theme-reference.d.cts +74 -0
  47. package/dist/theme-reference.d.ts +74 -0
  48. package/dist/theme-reference.js +1 -1
  49. package/dist/voice-worklet-player.cjs +2 -2
  50. package/dist/voice-worklet-player.js +2 -2
  51. package/dist/webmcp-polyfill.js +2 -2
  52. package/dist/widget.css +1 -1
  53. package/package.json +2 -3
  54. package/src/artifacts-session.test.ts +178 -0
  55. package/src/client.test.ts +500 -1
  56. package/src/client.ts +285 -93
  57. package/src/components/artifact-card.test.ts +333 -0
  58. package/src/components/artifact-card.ts +75 -28
  59. package/src/components/artifact-inline.test.ts +1328 -0
  60. package/src/components/artifact-inline.ts +920 -0
  61. package/src/components/artifact-pane.test.ts +1042 -0
  62. package/src/components/artifact-pane.ts +440 -131
  63. package/src/components/artifact-preview.test.ts +1155 -0
  64. package/src/components/artifact-preview.ts +994 -0
  65. package/src/components/pill-composer-builder.test.ts +6 -2
  66. package/src/components/pill-composer-builder.ts +6 -6
  67. package/src/components/reasoning-bubble.ts +1 -13
  68. package/src/components/registry.ts +38 -3
  69. package/src/components/tool-bubble.ts +1 -13
  70. package/src/defaults.ts +1 -0
  71. package/src/generated/runtype-openapi-contract.ts +55 -3
  72. package/src/index-core.ts +20 -1
  73. package/src/index.ts +8 -0
  74. package/src/markdown-parsers-loader.test.ts +158 -0
  75. package/src/markdown-parsers-loader.ts +74 -9
  76. package/src/runtime/host-layout.test.ts +163 -0
  77. package/src/runtime/host-layout.ts +110 -7
  78. package/src/runtime/init.ts +18 -61
  79. package/src/runtime/persist-state.test.ts +118 -0
  80. package/src/session.ts +76 -22
  81. package/src/styles/widget.css +773 -26
  82. package/src/theme-editor/preview.ts +2 -0
  83. package/src/theme-editor/sections.test.ts +26 -1
  84. package/src/theme-editor/sections.ts +10 -2
  85. package/src/theme-reference.ts +2 -2
  86. package/src/tool-call-display-defaults.test.ts +1 -0
  87. package/src/types/theme.ts +77 -0
  88. package/src/types.ts +516 -17
  89. package/src/ui.artifact-pane-gating.test.ts +636 -0
  90. package/src/ui.component-directive.test.ts +104 -0
  91. package/src/ui.composer-bar.test.ts +60 -2
  92. package/src/ui.detached-panel.test.ts +1049 -0
  93. package/src/ui.scroll-additive.test.ts +1 -1
  94. package/src/ui.streaming-coalescing.test.ts +312 -0
  95. package/src/ui.tool-display.test.ts +51 -0
  96. package/src/ui.ts +933 -214
  97. package/src/utils/artifact-custom-actions.ts +128 -0
  98. package/src/utils/artifact-display.test.ts +42 -0
  99. package/src/utils/artifact-display.ts +84 -0
  100. package/src/utils/artifact-file.test.ts +116 -0
  101. package/src/utils/artifact-file.ts +117 -0
  102. package/src/utils/artifact-gate.test.ts +112 -5
  103. package/src/utils/artifact-gate.ts +39 -14
  104. package/src/utils/artifact-loading-status.ts +55 -0
  105. package/src/utils/artifact-status-label.ts +190 -0
  106. package/src/utils/buttons.ts +7 -1
  107. package/src/utils/code-highlight.test.ts +186 -0
  108. package/src/utils/code-highlight.ts +400 -0
  109. package/src/utils/icons.ts +2 -0
  110. package/src/utils/roving-tablist.test.ts +152 -0
  111. package/src/utils/roving-tablist.ts +111 -0
  112. package/src/utils/spinner.ts +45 -0
  113. package/src/utils/theme.test.ts +48 -0
  114. package/src/utils/theme.ts +7 -0
  115. package/src/utils/tokens.ts +91 -0
  116. package/src/utils/tool-loading-animation.test.ts +32 -0
  117. package/src/utils/tool-loading-animation.ts +24 -0
  118. package/dist/chunk-DFBSCFYN.js +0 -1
  119. package/dist/runtype-tts-entry-HFUV2UF7.js +0 -1
  120. package/dist/session-reconnect-U77QFUR7.js +0 -1
package/dist/index.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { IconNode } from 'lucide';
2
+ import { Marked } from 'marked';
3
+ import DOMPurify from 'dompurify';
2
4
 
3
5
  /**
4
6
  * Plugin interface for customizing widget components
@@ -447,6 +449,10 @@ interface PanelTokens extends ComponentTokenSet {
447
449
  maxWidth: string;
448
450
  height: string;
449
451
  maxHeight: string;
452
+ /** Gap between the detached panel and its region edges. Only used when detached. */
453
+ inset?: string;
454
+ /** Background of the region revealed behind a detached panel. */
455
+ canvasBackground?: string;
450
456
  }
451
457
  interface HeaderTokens extends ComponentTokenSet {
452
458
  background: TokenReference<'color'>;
@@ -611,6 +617,14 @@ interface ArtifactToolbarTokens {
611
617
  iconBorder?: string;
612
618
  toggleGroupGap?: string;
613
619
  toggleBorderRadius?: string;
620
+ /** Inner padding of the segmented view/source toggle pill. */
621
+ toggleGroupPadding?: string;
622
+ /** Border of the segmented view/source toggle pill (e.g., `none`). */
623
+ toggleGroupBorder?: string;
624
+ /** Corner radius of the segmented view/source toggle pill. */
625
+ toggleGroupBorderRadius?: string;
626
+ /** Background of the segmented view/source toggle pill. */
627
+ toggleGroupBackground?: string;
614
628
  copyBackground?: string;
615
629
  copyBorder?: string;
616
630
  copyColor?: string;
@@ -642,6 +656,16 @@ interface ArtifactTabTokens {
642
656
  /** Tab list container padding (CSS shorthand). */
643
657
  listPadding?: string;
644
658
  }
659
+ /** Artifact reference card (chat thread) chrome. */
660
+ interface ArtifactCardTokens {
661
+ background?: string;
662
+ /** Full border shorthand (e.g. `1px solid #e5e7eb`). */
663
+ border?: string;
664
+ borderRadius?: string;
665
+ hoverBackground?: string;
666
+ /** Border color on hover. */
667
+ hoverBorderColor?: string;
668
+ }
645
669
  /** Artifact pane chrome. */
646
670
  interface ArtifactPaneTokens {
647
671
  /**
@@ -652,6 +676,54 @@ interface ArtifactPaneTokens {
652
676
  background?: string;
653
677
  toolbarBackground?: string;
654
678
  }
679
+ /** Inline artifact block chrome (`display: "inline"` file preview). */
680
+ interface ArtifactInlineTokens {
681
+ /** Background of the inline preview frame. */
682
+ background?: string;
683
+ /** Full border shorthand for the frame (e.g. `1px solid #e5e7eb`). */
684
+ border?: string;
685
+ /** Border radius of the inline preview frame. */
686
+ borderRadius?: string;
687
+ /** Background of the title/toolbar chrome bar. */
688
+ chromeBackground?: string;
689
+ /** Bottom border of the title bar. */
690
+ chromeBorder?: string;
691
+ /** Title text color in the chrome bar (artifact basename). */
692
+ titleColor?: string;
693
+ /** Muted text color for the type label / streaming status. */
694
+ mutedColor?: string;
695
+ /** Preview iframe height inside the inline body. */
696
+ frameHeight?: string;
697
+ }
698
+ /**
699
+ * Syntax-highlighted artifact source view (pane + inline), rendered by
700
+ * `utils/code-highlight.ts`. One Light defaults ship in `widget.css`, with a
701
+ * One Dark override keyed off the widget's resolved color scheme (the
702
+ * `data-persona-color-scheme` root attribute, not the OS preference); set any
703
+ * of these to retheme the tokenizer palette and the line-number gutter.
704
+ */
705
+ interface CodeTokens {
706
+ /** Keywords, booleans, null (e.g. `const`, `true`). */
707
+ keywordColor?: string;
708
+ /** String and template literals; HTML attribute values. */
709
+ stringColor?: string;
710
+ /** Line and block comments. */
711
+ commentColor?: string;
712
+ /** Numeric literals; CSS hex colors / units. */
713
+ numberColor?: string;
714
+ /** HTML tag brackets + names; doctype. */
715
+ tagColor?: string;
716
+ /** HTML attribute names. */
717
+ attrColor?: string;
718
+ /** CSS property names; JSON object keys. */
719
+ propertyColor?: string;
720
+ /** Line-number gutter digits. */
721
+ lineNumberColor?: string;
722
+ /** Right border of the line-number gutter. */
723
+ gutterBorderColor?: string;
724
+ /** Background of the source-view code sheet (defaults to One Light/Dark editor background). */
725
+ background?: string;
726
+ }
655
727
  /** Icon button chrome (used by createIconButton). */
656
728
  interface IconButtonTokens {
657
729
  background?: string;
@@ -721,9 +793,13 @@ interface ComponentTokens {
721
793
  toolbar?: ArtifactToolbarTokens;
722
794
  tab?: ArtifactTabTokens;
723
795
  pane?: ArtifactPaneTokens;
796
+ card?: ArtifactCardTokens;
797
+ inline?: ArtifactInlineTokens;
724
798
  };
725
799
  /** Collapsible widget chrome (tool/reasoning/approval bubbles). */
726
800
  collapsibleWidget?: CollapsibleWidgetTokens;
801
+ /** Syntax-highlighted artifact source view (tokenizer palette + gutter). */
802
+ code?: CodeTokens;
727
803
  }
728
804
  interface PaletteExtras {
729
805
  transitions?: Record<string, string>;
@@ -793,6 +869,7 @@ type RuntypeExecutionStreamEvent = ({
793
869
  totalSteps?: number;
794
870
  type: "execution_start";
795
871
  }) | ({
872
+ claudeManagedAgentId?: string;
796
873
  completedAt?: string;
797
874
  durationMs?: number;
798
875
  executionId: string;
@@ -837,6 +914,15 @@ type RuntypeExecutionStreamEvent = ({
837
914
  completedAt?: string;
838
915
  content?: string;
839
916
  cost?: number;
917
+ estimatedContextBreakdown?: {
918
+ categories: Record<string, {
919
+ chars: number;
920
+ estimatedTokens: number;
921
+ }>;
922
+ contextWindowSize?: number;
923
+ estimatedTotalTokens: number;
924
+ estimatedUtilizationPercent?: number;
925
+ };
840
926
  executionId: string;
841
927
  fallback?: {
842
928
  attempts: Array<{
@@ -874,6 +960,7 @@ type RuntypeExecutionStreamEvent = ({
874
960
  type: "step_start";
875
961
  } | ({
876
962
  completedAt?: string;
963
+ cost?: number;
877
964
  durationMs?: number;
878
965
  error?: string;
879
966
  executionId: string;
@@ -979,6 +1066,11 @@ type RuntypeExecutionStreamEvent = ({
979
1066
  artifactType: "markdown" | "component";
980
1067
  component?: string;
981
1068
  executionId?: string;
1069
+ file?: {
1070
+ language?: string;
1071
+ mimeType: string;
1072
+ path: string;
1073
+ };
982
1074
  id: string;
983
1075
  seq?: number;
984
1076
  title?: string;
@@ -1087,6 +1179,14 @@ type RuntypeExecutionStreamEvent = ({
1087
1179
  awaitReason?: string;
1088
1180
  awaitedAt?: string;
1089
1181
  crawlId?: string;
1182
+ elicitation?: {
1183
+ message: string;
1184
+ mode: "form" | "url";
1185
+ pauseCount?: number;
1186
+ requestedSchema?: Record<string, unknown>;
1187
+ serverName?: string;
1188
+ url?: string;
1189
+ };
1090
1190
  executionId: string;
1091
1191
  origin?: "webmcp" | "sdk";
1092
1192
  pageOrigin?: string;
@@ -1186,6 +1286,14 @@ type RuntypeFlowSSEEvent = {
1186
1286
  awaitReason?: string;
1187
1287
  awaitedAt: string;
1188
1288
  crawlId?: string;
1289
+ elicitation?: {
1290
+ message: string;
1291
+ mode: "form" | "url";
1292
+ pauseCount?: number;
1293
+ requestedSchema?: Record<string, unknown>;
1294
+ serverName?: string;
1295
+ url?: string;
1296
+ };
1189
1297
  executionId?: string;
1190
1298
  flowId: string;
1191
1299
  origin?: "webmcp" | "sdk";
@@ -1236,7 +1344,7 @@ type RuntypeFlowSSEEvent = {
1236
1344
  completedAt?: string;
1237
1345
  duration?: number;
1238
1346
  durationMs?: number;
1239
- error?: string;
1347
+ error?: string | null;
1240
1348
  executionId?: string;
1241
1349
  executionTime?: number;
1242
1350
  id?: string;
@@ -1280,13 +1388,21 @@ type RuntypeFlowSSEEvent = {
1280
1388
  totalSteps: number;
1281
1389
  type: "step_skip";
1282
1390
  when: string;
1283
- } | {
1391
+ } | ({
1392
+ elicitation?: {
1393
+ message: string;
1394
+ mode: "form" | "url";
1395
+ pauseCount?: number;
1396
+ requestedSchema?: Record<string, unknown>;
1397
+ serverName?: string;
1398
+ url?: string;
1399
+ };
1284
1400
  executionId?: string;
1285
1401
  reason?: string;
1286
1402
  seq?: number;
1287
1403
  type: "step_await";
1288
1404
  [key: string]: unknown;
1289
- } | ({
1405
+ }) | ({
1290
1406
  agentContext?: {
1291
1407
  executionId: string;
1292
1408
  iteration: number;
@@ -1490,6 +1606,18 @@ type RuntypeClientChatRequest = {
1490
1606
  };
1491
1607
  type RuntypeClientChatStreamEvent = RuntypeExecutionStreamEvent;
1492
1608
  type RuntypeClientResumeRequest = {
1609
+ clientTools?: Array<{
1610
+ description: string;
1611
+ name: string;
1612
+ origin?: "webmcp" | "sdk";
1613
+ pageOrigin?: string;
1614
+ parametersSchema: {
1615
+ type: "object";
1616
+ [key: string]: unknown;
1617
+ };
1618
+ untrustedContentHint?: boolean;
1619
+ }>;
1620
+ clientToolsFingerprint?: string;
1493
1621
  executionId: string;
1494
1622
  messages?: Array<{
1495
1623
  content: string | (Array<{
@@ -1569,6 +1697,162 @@ type ResolvedTarget = {
1569
1697
  payload: Record<string, unknown>;
1570
1698
  };
1571
1699
 
1700
+ /**
1701
+ * Curated registry of lucide icons available to `renderLucideIcon`.
1702
+ *
1703
+ * The widget used to do `import * as icons from "lucide"` and look up
1704
+ * icons dynamically by string. That defeated tree-shaking, so the IIFE
1705
+ * (CDN/script-tag) bundle shipped all 1640 lucide icons (~400KB of icon
1706
+ * data) regardless of which we actually used. This explicit registry
1707
+ * lets the bundler drop any icon not listed here.
1708
+ *
1709
+ * Trade-off: `renderLucideIcon(name)` is now a *closed set*. Names not
1710
+ * in this map return `null` and log a warning, exactly as a typo did
1711
+ * before. The registry is intentionally generous (~110 icons) so that
1712
+ * custom `ComponentRenderer` authors rarely hit a missing-icon dead end.
1713
+ *
1714
+ * To add icons: add a named import above and a row in `LUCIDE_ICONS`,
1715
+ * keyed by the lucide kebab-case name (matches their filename and
1716
+ * https://lucide.dev/icons).
1717
+ *
1718
+ * See `packages/widget/docs/icon-registry-shortlist.md` for the full
1719
+ * curation rationale and which icons were considered but excluded.
1720
+ */
1721
+ declare const LUCIDE_ICONS: {
1722
+ readonly activity: IconNode;
1723
+ readonly "arrow-down": IconNode;
1724
+ readonly "arrow-up": IconNode;
1725
+ readonly "arrow-up-right": IconNode;
1726
+ readonly bot: IconNode;
1727
+ readonly "chevron-down": IconNode;
1728
+ readonly "chevron-up": IconNode;
1729
+ readonly "chevron-right": IconNode;
1730
+ readonly "chevron-left": IconNode;
1731
+ readonly check: IconNode;
1732
+ readonly clipboard: IconNode;
1733
+ readonly "clipboard-copy": IconNode;
1734
+ readonly "code-xml": IconNode;
1735
+ readonly copy: IconNode;
1736
+ readonly file: IconNode;
1737
+ readonly "file-code": IconNode;
1738
+ readonly "file-spreadsheet": IconNode;
1739
+ readonly "file-text": IconNode;
1740
+ readonly "image-plus": IconNode;
1741
+ readonly loader: IconNode;
1742
+ readonly "loader-circle": IconNode;
1743
+ readonly mic: IconNode;
1744
+ readonly paperclip: IconNode;
1745
+ readonly "refresh-cw": IconNode;
1746
+ readonly search: IconNode;
1747
+ readonly send: IconNode;
1748
+ readonly "shield-alert": IconNode;
1749
+ readonly "shield-check": IconNode;
1750
+ readonly "shield-x": IconNode;
1751
+ readonly square: IconNode;
1752
+ readonly "thumbs-down": IconNode;
1753
+ readonly "thumbs-up": IconNode;
1754
+ readonly upload: IconNode;
1755
+ readonly "volume-2": IconNode;
1756
+ readonly x: IconNode;
1757
+ readonly user: IconNode;
1758
+ readonly mail: IconNode;
1759
+ readonly phone: IconNode;
1760
+ readonly calendar: IconNode;
1761
+ readonly clock: IconNode;
1762
+ readonly building: IconNode;
1763
+ readonly "map-pin": IconNode;
1764
+ readonly lock: IconNode;
1765
+ readonly key: IconNode;
1766
+ readonly "credit-card": IconNode;
1767
+ readonly "at-sign": IconNode;
1768
+ readonly hash: IconNode;
1769
+ readonly globe: IconNode;
1770
+ readonly link: IconNode;
1771
+ readonly "circle-check": IconNode;
1772
+ readonly "circle-x": IconNode;
1773
+ readonly "triangle-alert": IconNode;
1774
+ readonly info: IconNode;
1775
+ readonly ban: IconNode;
1776
+ readonly shield: IconNode;
1777
+ readonly "arrow-left": IconNode;
1778
+ readonly "arrow-right": IconNode;
1779
+ readonly "external-link": IconNode;
1780
+ readonly ellipsis: IconNode;
1781
+ readonly "ellipsis-vertical": IconNode;
1782
+ readonly menu: IconNode;
1783
+ readonly house: IconNode;
1784
+ readonly plus: IconNode;
1785
+ readonly minus: IconNode;
1786
+ readonly pencil: IconNode;
1787
+ readonly trash: IconNode;
1788
+ readonly "trash-2": IconNode;
1789
+ readonly save: IconNode;
1790
+ readonly download: IconNode;
1791
+ readonly share: IconNode;
1792
+ readonly funnel: IconNode;
1793
+ readonly settings: IconNode;
1794
+ readonly "rotate-cw": IconNode;
1795
+ readonly maximize: IconNode;
1796
+ readonly minimize: IconNode;
1797
+ readonly "shopping-cart": IconNode;
1798
+ readonly "shopping-bag": IconNode;
1799
+ readonly package: IconNode;
1800
+ readonly truck: IconNode;
1801
+ readonly tag: IconNode;
1802
+ readonly gift: IconNode;
1803
+ readonly receipt: IconNode;
1804
+ readonly wallet: IconNode;
1805
+ readonly store: IconNode;
1806
+ readonly "dollar-sign": IconNode;
1807
+ readonly percent: IconNode;
1808
+ readonly play: IconNode;
1809
+ readonly pause: IconNode;
1810
+ readonly "volume-x": IconNode;
1811
+ readonly camera: IconNode;
1812
+ readonly image: IconNode;
1813
+ readonly film: IconNode;
1814
+ readonly headphones: IconNode;
1815
+ readonly "message-circle": IconNode;
1816
+ readonly "message-square": IconNode;
1817
+ readonly bell: IconNode;
1818
+ readonly heart: IconNode;
1819
+ readonly star: IconNode;
1820
+ readonly eye: IconNode;
1821
+ readonly "eye-off": IconNode;
1822
+ readonly bookmark: IconNode;
1823
+ readonly "calendar-days": IconNode;
1824
+ readonly history: IconNode;
1825
+ readonly timer: IconNode;
1826
+ readonly folder: IconNode;
1827
+ readonly "folder-open": IconNode;
1828
+ readonly files: IconNode;
1829
+ readonly sparkles: IconNode;
1830
+ readonly zap: IconNode;
1831
+ readonly sun: IconNode;
1832
+ readonly moon: IconNode;
1833
+ readonly flag: IconNode;
1834
+ readonly monitor: IconNode;
1835
+ readonly smartphone: IconNode;
1836
+ };
1837
+ /**
1838
+ * Names of lucide icons that ship with the widget. Names not in this
1839
+ * union return `null` from `renderLucideIcon` (with a console warning).
1840
+ */
1841
+ type IconName = keyof typeof LUCIDE_ICONS;
1842
+ /**
1843
+ * Renders a lucide icon as an inline SVG element. Works inside Shadow
1844
+ * DOM and requires no CSS.
1845
+ *
1846
+ * @param iconName - A lucide kebab-case name from the registry. See
1847
+ * `IconName` for the full list, or `docs/icon-registry-shortlist.md`
1848
+ * for rationale.
1849
+ * @param size - The size in pixels (number) or any CSS length string.
1850
+ * @param color - Stroke color (default: "currentColor").
1851
+ * @param strokeWidth - Stroke width (default: 2).
1852
+ * @returns SVGElement, or null if the name is not in the registry.
1853
+ */
1854
+ declare const renderLucideIcon: (iconName: IconName | (string & {}), size?: number | string, color?: string, strokeWidth?: number) => SVGElement | null;
1855
+
1572
1856
  /**
1573
1857
  * Text content part for multi-modal messages
1574
1858
  */
@@ -2231,7 +2515,13 @@ type AgentWidgetControllerEventMap = {
2231
2515
  * new artifact content arrives or the host calls `showArtifacts()` on the widget handle.
2232
2516
  */
2233
2517
  type AgentWidgetArtifactsLayoutConfig = {
2234
- /** Flex gap between chat column and artifact pane. @default 0.5rem */
2518
+ /**
2519
+ * Flex gap between chat column and artifact pane.
2520
+ * @default 0 (welded); detached uses the panel inset
2521
+ * @remarks In welded appearances (`panel` / `seamless`) a nonzero gap opens a
2522
+ * visible seam in the single card. It is honored geometrically (resize clamps
2523
+ * and the seam handle account for it) but is usually undesired.
2524
+ */
2235
2525
  splitGap?: string;
2236
2526
  /** Artifact column width in split mode. @default 40% */
2237
2527
  paneWidth?: string;
@@ -2262,16 +2552,39 @@ type AgentWidgetArtifactsLayoutConfig = {
2262
2552
  /** Optional max artifact width cap while resizing (`px` only). Layout still bounds by chat min width. */
2263
2553
  resizableMaxWidth?: string;
2264
2554
  /**
2265
- * Visual treatment for the artifact column in split mode.
2266
- * - `'panel'`: bordered sidebar with left border, gap, and shadow (default).
2267
- * - `'seamless'`: flush with chat: no border or shadow, container background, zero gap.
2555
+ * Visual treatment for the artifact column in a desktop split.
2556
+ * - `'panel'`: one welded card (border + radius wrap chat + pane) with a hairline
2557
+ * divider on the pane's chat-facing edge, zero gap (default).
2558
+ * - `'seamless'`: the same welded card with no internal divider or chrome, zero gap.
2559
+ * - `'detached'`: two separate elevated cards: gap from `--persona-panel-inset`,
2560
+ * all-side border and radius on each, and canvas background behind the split.
2561
+ * In an inline embed this also insets the split from the container edges on all
2562
+ * sides (the page canvas shows through), so the all-side margin no longer requires
2563
+ * `launcher.detachedPanel`.
2564
+ *
2565
+ * Default is `'panel'` unless `launcher.detachedPanel` is true, in which case an unset
2566
+ * `paneAppearance` resolves to `'detached'`. An explicit value always wins.
2268
2567
  * @default 'panel'
2269
2568
  */
2270
- paneAppearance?: "panel" | "seamless";
2569
+ paneAppearance?: "panel" | "seamless" | "detached";
2271
2570
  /** Border radius on the artifact pane (CSS length). Works with any `paneAppearance`. */
2272
2571
  paneBorderRadius?: string;
2273
2572
  /** CSS `box-shadow` on the artifact pane. Set `"none"` to suppress the default shadow. */
2274
2573
  paneShadow?: string;
2574
+ /**
2575
+ * CSS `box-shadow` for the chat column card in a detached split. Defaults to the same
2576
+ * elevation as the artifact pane; set to `"none"` to keep the chat flat while the pane stays raised.
2577
+ */
2578
+ chatShadow?: string;
2579
+ /**
2580
+ * Chat column surface in a detached split. `"card"` (default) renders the chat as an inset card
2581
+ * matching the artifact pane; `"flush"` renders the chat flush with the container (no border, radius,
2582
+ * or shadow) and insets only the artifact pane, so the chat is flat background and the pane floats.
2583
+ * Only affects an inline-embedded detached split (the container-filling case); in floating, docked,
2584
+ * or sidebar modes it falls back to the card look.
2585
+ * @default 'card'
2586
+ */
2587
+ chatSurface?: "card" | "flush";
2275
2588
  /**
2276
2589
  * Full `border` shorthand for the artifact `<aside>` (all sides). Overrides default pane borders.
2277
2590
  * Example: `"1px solid #cccccc"`.
@@ -2283,14 +2596,12 @@ type AgentWidgetArtifactsLayoutConfig = {
2283
2596
  */
2284
2597
  paneBorderLeft?: string;
2285
2598
  /**
2286
- * Desktop split only (not narrow-host drawer / not ≤640px): square the **main chat card’s**
2287
- * top-right and bottom-right radii, and round the **artifact pane’s** top-right and bottom-right
2288
- * to match `persona-rounded-2xl` (`--persona-radius-lg`) so the two columns read as one shell.
2599
+ * @deprecated No-op. Panel and seamless splits now weld into one card by default.
2289
2600
  */
2290
2601
  unifiedSplitChrome?: boolean;
2291
2602
  /**
2292
- * When `unifiedSplitChrome` is true, outer-right corner radius on the artifact column (CSS length).
2293
- * @default matches theme large radius (`--persona-radius-lg`)
2603
+ * Desktop welded split only: override the artifact pane's outer-right corner radius (CSS length).
2604
+ * @default matches the panel radius (`--persona-panel-radius`)
2294
2605
  */
2295
2606
  unifiedSplitOuterRadius?: string;
2296
2607
  /**
@@ -2310,6 +2621,10 @@ type AgentWidgetArtifactsLayoutConfig = {
2310
2621
  * @default 'default'
2311
2622
  */
2312
2623
  toolbarPreset?: "default" | "document";
2624
+ /** Visible title in the artifact toolbar. @default "Artifacts" */
2625
+ toolbarTitle?: string;
2626
+ /** Label for the artifact dismiss control. @default "Close" */
2627
+ closeButtonLabel?: string;
2313
2628
  /**
2314
2629
  * When `toolbarPreset` is `document`, show a visible "Copy" label next to the copy icon.
2315
2630
  */
@@ -2324,6 +2639,17 @@ type AgentWidgetArtifactsLayoutConfig = {
2324
2639
  documentToolbarToggleActiveBackground?: string;
2325
2640
  /** Active view/source toggle border color. Sets `--persona-artifact-doc-toggle-active-border`. */
2326
2641
  documentToolbarToggleActiveBorderColor?: string;
2642
+ /** Show an expand/collapse toggle in the artifact toolbar (both presets). Expanded fills the widget with the pane and hides the chat column. Default: false. */
2643
+ showExpandToggle?: boolean;
2644
+ /** Show the copy control in the `default` toolbar preset (the `document` preset always shows it). Default: false. */
2645
+ showCopyButton?: boolean;
2646
+ /** Edge fade on the scrollable tab strip. true = both ends (dynamic). @default true */
2647
+ tabFade?: boolean | {
2648
+ start?: boolean;
2649
+ end?: boolean;
2650
+ };
2651
+ /** Tab fade width (CSS length). @default 24px */
2652
+ tabFadeSize?: string;
2327
2653
  /**
2328
2654
  * Invoked when the document toolbar Refresh control is used (before the pane re-renders).
2329
2655
  * Use to replay `connectStream`, refetch, etc.
@@ -2347,20 +2673,349 @@ type AgentWidgetArtifactsLayoutConfig = {
2347
2673
  jsonPayload: string;
2348
2674
  }) => void | Promise<void>;
2349
2675
  };
2676
+ type PersonaArtifactDisplayMode = "card" | "panel" | "inline";
2677
+ /** Context handed to custom artifact actions. Content fields are best-effort: resolved from live session state or, after a refresh, from the persisted reference-card payload. */
2678
+ type PersonaArtifactActionContext = {
2679
+ artifactId: string | null;
2680
+ title: string;
2681
+ artifactType: string;
2682
+ markdown?: string;
2683
+ file?: PersonaArtifactFileMeta;
2684
+ /** Component artifacts: pretty-printed { component, props } JSON. */
2685
+ jsonPayload?: string;
2686
+ };
2687
+ /**
2688
+ * Context passed to a `features.artifacts.statusLabel` function on every
2689
+ * artifact streaming update, once per visible surface. Treat it as read-only:
2690
+ * the function should be pure and fast (it runs per streaming delta, per
2691
+ * surface).
2692
+ */
2693
+ type PersonaArtifactStatusLabelContext = {
2694
+ artifactId: string;
2695
+ artifactType: "markdown" | "component";
2696
+ title?: string;
2697
+ /** The default subject, e.g. "document", "component", or a file type label like "HTML file". */
2698
+ typeLabel: string;
2699
+ file?: PersonaArtifactFileMeta;
2700
+ /** Accumulated streamed content length so far (0 for component artifacts). */
2701
+ chars: number;
2702
+ /** Accumulated line count so far (0 for component artifacts). */
2703
+ lines: number;
2704
+ /** Milliseconds since this artifact's first streaming update was seen. */
2705
+ elapsedMs: number;
2706
+ /** Lazy accessor for the accumulated markdown source (empty string for component artifacts). Call only if needed; parsing cost is opt-in. */
2707
+ content: () => string;
2708
+ /** Which surface is asking, so hosts can shorten for cramped spots. */
2709
+ surface: "card" | "inline-chrome" | "status-body";
2710
+ };
2711
+ /** A custom action button rendered in an artifact toolbar/card slot. */
2712
+ type PersonaArtifactCustomAction = {
2713
+ /** Stable id, used for DOM wiring and keyed re-renders. */
2714
+ id: string;
2715
+ /** Accessible label; also the visible text when showLabel is true. */
2716
+ label: string;
2717
+ /** Registry icon name, or a factory returning your own element (e.g. a brand SVG). The factory result is author-owned code, not sanitized wire data. */
2718
+ icon?: IconName | (() => HTMLElement | SVGElement);
2719
+ /** Render icon + text instead of icon-only. Default: false. */
2720
+ showLabel?: boolean;
2721
+ /** Per-artifact gate, evaluated on each render. Omitted = always visible. */
2722
+ visible?: (ctx: PersonaArtifactActionContext) => boolean;
2723
+ /** May be async; rejections are swallowed like built-in action errors. */
2724
+ onClick: (ctx: PersonaArtifactActionContext) => void | Promise<void>;
2725
+ };
2350
2726
  type AgentWidgetArtifactsFeature = {
2351
2727
  /** When true, Persona shows the artifact pane and handles artifact_* SSE events */
2352
2728
  enabled?: boolean;
2353
2729
  /** If set, artifact events for other types are ignored */
2354
2730
  allowedTypes?: PersonaArtifactKind[];
2731
+ /**
2732
+ * Where artifact bodies render. A single mode applies to all artifacts;
2733
+ * the object form sets a default plus per-type overrides.
2734
+ * Defaults to "panel" (current behavior).
2735
+ */
2736
+ display?: PersonaArtifactDisplayMode | {
2737
+ default?: PersonaArtifactDisplayMode;
2738
+ byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayMode>>;
2739
+ };
2355
2740
  /** Split / drawer dimensions and launcher widen behavior */
2356
2741
  layout?: AgentWidgetArtifactsLayoutConfig;
2357
2742
  /**
2358
- * Called when an artifact card action is triggered (open, download).
2359
- * Return `true` to prevent the default behavior.
2743
+ * Controls inline preview of previewable file artifacts (HTML/SVG written by
2744
+ * a Claude Managed agent). When a markdown artifact carries `file` metadata,
2745
+ * the pane can render an isolated `<iframe srcdoc>` sandbox instead of a code
2746
+ * block.
2747
+ */
2748
+ filePreview?: {
2749
+ /** Enable rendered preview for html/svg files. Defaults to enabled. Set false to force source view. */
2750
+ enabled?: boolean;
2751
+ /**
2752
+ * `sandbox` attribute for the preview iframe. Defaults to `"allow-scripts"`.
2753
+ * `allow-same-origin` is stripped (with a console warning) unless
2754
+ * `dangerouslyAllowSameOrigin` is set: the opaque origin is what isolates
2755
+ * the preview from the host page. Embedder-trusted config.
2756
+ */
2757
+ iframeSandbox?: string;
2758
+ /**
2759
+ * Allows `allow-same-origin` to pass through `iframeSandbox`. Off by
2760
+ * default because it lets agent-written file content run with the host
2761
+ * page's origin (DOM, storage, credentialed requests). Only set this when
2762
+ * every previewed file source is fully trusted.
2763
+ */
2764
+ dangerouslyAllowSameOrigin?: boolean;
2765
+ /**
2766
+ * Loading treatment for the preview iframe. Default on.
2767
+ *
2768
+ * A sandboxed `iframe srcdoc` (opaque origin, `allow-scripts` only) paints
2769
+ * blank until its content renders — seconds for artifacts that pull CDN
2770
+ * scripts (React/Babel). The default shows a themed "Loading preview…"
2771
+ * overlay over the iframe, dismissed the instant the content signals it has
2772
+ * painted (an injected `postMessage` reporter) or a hard timeout elapses.
2773
+ *
2774
+ * `false` disables the overlay and the injected ready signal entirely (the
2775
+ * srcdoc becomes the raw file source, the prior behavior). An object tunes
2776
+ * the timing; omitted / `true` uses all defaults.
2777
+ */
2778
+ loading?: boolean | {
2779
+ /** Show the overlay only if the preview is not ready after this many ms. Default 200. */
2780
+ delayMs?: number;
2781
+ /** Once shown, keep the overlay visible at least this long (anti-flicker). Default 300. */
2782
+ minVisibleMs?: number;
2783
+ /** Give up waiting and reveal the iframe regardless after this many ms. Default 8000. */
2784
+ timeoutMs?: number;
2785
+ /**
2786
+ * Append the `postMessage` ready reporter to the srcdoc so the overlay
2787
+ * dismisses on first paint rather than the iframe `load` event (which
2788
+ * fires before post-DOMContentLoaded rendering like Babel compilation).
2789
+ * Default true. When false, the overlay dismisses on `load` + a double
2790
+ * `requestAnimationFrame`, or the timeout.
2791
+ */
2792
+ injectReadySignal?: boolean;
2793
+ /**
2794
+ * Escalation text shown beside the spinner after `labelDelayMs`.
2795
+ * Default `"Starting preview..."`. `false` renders an icon-only
2796
+ * indicator forever (no text ever). A short work-naming label is
2797
+ * added only after a delay by design — icon-first, with text reserved
2798
+ * for genuinely slow loads (per Geist/Sandpack guidance; HIG warns
2799
+ * against the vague word "loading").
2800
+ */
2801
+ label?: string | false;
2802
+ /**
2803
+ * Delay before the escalation label fades in, measured from when the
2804
+ * overlay actually becomes visible (i.e. after `delayMs`), not from
2805
+ * iframe creation. Default 2000.
2806
+ */
2807
+ labelDelayMs?: number;
2808
+ /**
2809
+ * Full replacement for the default indicator (spinner + escalation
2810
+ * label). Called once when the overlay is built; return any element
2811
+ * (a brand mark, skeleton, custom animation) to own the indicator
2812
+ * content entirely (the escalation-label logic is then skipped), or
2813
+ * return `null` to fall back to the default. A thrown error also falls
2814
+ * back. Mirrors `renderInline` / `renderCard`'s null-falls-back
2815
+ * contract. The overlay backdrop, timing, and dismissal stay
2816
+ * widget-owned either way.
2817
+ */
2818
+ renderIndicator?: (ctx: {
2819
+ artifactId: string;
2820
+ config: AgentWidgetConfig;
2821
+ }) => HTMLElement | null;
2822
+ };
2823
+ };
2824
+ /**
2825
+ * Custom action buttons for the artifact pane toolbar, rendered between the
2826
+ * refresh and expand/close controls in both toolbar presets. Re-read on live
2827
+ * config updates.
2828
+ */
2829
+ toolbarActions?: PersonaArtifactCustomAction[];
2830
+ /**
2831
+ * Custom action buttons for the artifact reference card, rendered before the
2832
+ * Download button on complete artifacts. Clicks are delegated, so they
2833
+ * survive re-renders and page refresh.
2834
+ */
2835
+ cardActions?: PersonaArtifactCustomAction[];
2836
+ /**
2837
+ * File chrome (title bar + toolbar) around inline preview blocks
2838
+ * (`display: "inline"`). Default when undefined: chrome on, with the built-in
2839
+ * Copy and Expand controls. Pass `false` to render the bare preview body
2840
+ * (frame → padded body, no chrome bar), or an object to toggle the built-in
2841
+ * controls individually.
2842
+ *
2843
+ * Note: default-on chrome adds a title bar and buttons to every existing
2844
+ * inline host on upgrade; set `inlineChrome: false` to opt out.
2845
+ */
2846
+ inlineChrome?: boolean | {
2847
+ /** Show the built-in Copy button (complete artifacts only). Default true. */
2848
+ showCopy?: boolean;
2849
+ /** Show the built-in Expand button (opens the pane for this artifact). Default true. */
2850
+ showExpand?: boolean;
2851
+ /**
2852
+ * Show the built-in rendered/source view toggle (complete artifacts
2853
+ * only). Default true. The toggle is availability-gated: it appears only
2854
+ * for file-backed markdown artifacts that have a rendered alternative to
2855
+ * their source (previewable HTML/SVG, or markdown-kind files), and never
2856
+ * when `inlineBody.viewMode: "source"` forces a source-only body. Plain
2857
+ * markdown and component artifacts don't get it (the pane toggle covers
2858
+ * those).
2859
+ */
2860
+ showViewToggle?: boolean;
2861
+ };
2862
+ /**
2863
+ * Custom action buttons for the inline chrome toolbar, rendered before the
2864
+ * built-in Copy/Expand controls on complete artifacts. Same shape as
2865
+ * `cardActions`; each action's `visible` gate is respected and clicks are
2866
+ * delegated, so they survive re-renders and page refresh.
2867
+ */
2868
+ inlineActions?: PersonaArtifactCustomAction[];
2869
+ /**
2870
+ * Replace the artifact tab strip entirely (Seam A). Return an element mounted in
2871
+ * place of the built-in `.persona-artifact-list`; the pane still owns the toolbar,
2872
+ * preview body, iframe reuse, and lazy-render gate. Re-invoked when the records or
2873
+ * selection change. Custom bars own their own accessibility; use `createRovingTablist`
2874
+ * to keep keyboard/tablist behavior. When set, the built-in strip (scroll, fade,
2875
+ * tablist) is not rendered.
2876
+ *
2877
+ * Return either a fresh element per call, or the SAME element updated in place.
2878
+ * Returning a stable element preserves internal state across selection changes:
2879
+ * the pane skips remounting an unchanged node, so a roving tablist keeps keyboard
2880
+ * focus on the selected tab (a fresh element per call drops focus and breaks
2881
+ * Arrow-key nav). See the reference bars in `apps/web/src/artifact-demo.ts`.
2882
+ */
2883
+ renderTabBar?: (ctx: {
2884
+ records: PersonaArtifactRecord[];
2885
+ selectedId: string | null;
2886
+ onSelect: (id: string) => void;
2887
+ }) => HTMLElement;
2888
+ /**
2889
+ * Body layout for inline artifact blocks (`display: "inline"`). Controls how
2890
+ * the block reserves height and behaves while a file/document artifact
2891
+ * streams, so the streaming source no longer grows an unbounded `<pre>` and
2892
+ * then snaps to the completed preview. Affects only the inline block; the
2893
+ * artifact pane is unchanged.
2894
+ *
2895
+ * Defaults (a behavior change from prior versions, which grew with content
2896
+ * during streaming): a fixed 320px streaming source window with tail-follow,
2897
+ * a top edge fade, and an animated streaming→complete swap. Pass
2898
+ * `height: "auto"` to restore the old grow-with-content streaming behavior.
2899
+ */
2900
+ inlineBody?: {
2901
+ /** What the body shows while streaming. Default `"source"`. */
2902
+ streamingView?: "source" | "status";
2903
+ /**
2904
+ * How the completed body renders. `"rendered"` (default) keeps the current
2905
+ * behavior: file previews in a sandboxed iframe, markdown through the
2906
+ * markdown pipeline. `"source"` always shows the raw syntax-highlighted
2907
+ * source instead — for hosts where the artifact is input to the host system
2908
+ * (a code editor, a query runner) rather than something to preview. Unlike
2909
+ * `filePreview.enabled: false`, this also covers markdown-kind files and
2910
+ * plain markdown artifacts. Component artifacts always render through the
2911
+ * registry.
2912
+ */
2913
+ viewMode?: "rendered" | "source";
2914
+ /**
2915
+ * Body height per state. A number reserves that many px for the whole body
2916
+ * region (border-box, padding included) with internal scroll — the
2917
+ * zero-layout-shift path; `"auto"` means content-sized. A
2918
+ * scalar applies to both the streaming and complete states; the object form
2919
+ * sets them independently. Default `320` for both states.
2920
+ *
2921
+ * Note: with `"auto"` on the complete state, non-iframe bodies (rendered
2922
+ * markdown, source view, component) are content-sized, but a file-preview
2923
+ * iframe cannot be content-sized without postMessage plumbing, so it falls
2924
+ * back to the CSS-var default (`--persona-artifact-inline-frame-height`,
2925
+ * 320px).
2926
+ *
2927
+ * Numeric heights are applied via the CSS var
2928
+ * `--persona-artifact-inline-body-height` on the block root. The older
2929
+ * `--persona-artifact-inline-frame-height` var still overrides the iframe
2930
+ * height when this one is unset, so themes pinned to it keep working.
2931
+ */
2932
+ height?: number | "auto" | {
2933
+ streaming?: number | "auto";
2934
+ complete?: number | "auto";
2935
+ };
2936
+ /**
2937
+ * Tail-follow the newest streamed lines in a fixed-height source window: if
2938
+ * the viewport is already at the bottom, keep it pinned as content arrives;
2939
+ * if the reader scrolled up, don't fight them. Only meaningful for a numeric
2940
+ * streaming height. Default `true`.
2941
+ *
2942
+ * Precedence: ignored when `overflow: "clip"` (a clipped window shows the
2943
+ * top of the document and never scrolls, so there is no tail to follow).
2944
+ */
2945
+ followOutput?: boolean;
2946
+ /**
2947
+ * How a fixed-height source window handles content taller than the window.
2948
+ *
2949
+ * - `"scroll"` (default) — the current behavior: an internally scrollable
2950
+ * window that tail-follows the newest streamed lines (see `followOutput`),
2951
+ * so the reader sees the growing tail of the document.
2952
+ * - `"clip"` — a fixed-height window that shows the TOP of the document,
2953
+ * `overflow: hidden` with no internal scroll and no tail-follow
2954
+ * (`followOutput` is ignored in this mode). When content overflows the
2955
+ * window a bottom edge fade signals there is more below (the top is always
2956
+ * visible, so a top fade never applies); an explicit `fadeMask` still wins
2957
+ * over this clip-mode default. When the inline chrome's Expand control is
2958
+ * enabled the whole body doubles as an expand hitbox (click / Enter / Space
2959
+ * opens the artifact in the pane), matching the industry inline-card
2960
+ * pattern; otherwise the clip is purely visual.
2961
+ *
2962
+ * Only meaningful for a numeric streaming/complete height. Default
2963
+ * `"scroll"`.
2964
+ */
2965
+ overflow?: "scroll" | "clip";
2966
+ /**
2967
+ * Edge fade masks on the fixed-height streaming window (a top fade signals
2968
+ * clipped content above, a bottom fade signals clipped content below). Each
2969
+ * fade renders only when content is actually clipped on that edge, so with
2970
+ * tail-follow pinned at the bottom the bottom fade stays inert until the
2971
+ * reader scrolls up mid-stream. `true` = `{ top: true, bottom: true }`,
2972
+ * `false` = none. Default `{ top: true, bottom: true }`.
2973
+ */
2974
+ fadeMask?: boolean | {
2975
+ top?: boolean;
2976
+ bottom?: boolean;
2977
+ };
2978
+ /**
2979
+ * Animate the streaming→complete body swap. `"auto"` uses the View
2980
+ * Transitions API when supported and `prefers-reduced-motion` is off;
2981
+ * `"none"` swaps instantly. Default `"auto"`.
2982
+ */
2983
+ transition?: "auto" | "none";
2984
+ /**
2985
+ * What the block becomes once the artifact completes.
2986
+ *
2987
+ * - `"inline"` (default) — the streamed body stays inline forever, as
2988
+ * configured by the other `inlineBody` options.
2989
+ * - `"card"` — the block streams inline as configured, then collapses to the
2990
+ * compact artifact reference card once the artifact completes (the Copilot
2991
+ * "chiclet" / Claude side-panel handoff pattern), keeping the thread
2992
+ * scannable. The collapse plays as a short CSS height transition (skipped
2993
+ * under `prefers-reduced-motion`); it does not use the View Transitions
2994
+ * API, so `transition` does not affect it. After the collapse the card's
2995
+ * normal actions apply (click opens the artifact pane). `viewMode`, the
2996
+ * inline rendered/source view toggle, `inlineActions`, and inline copy are
2997
+ * streaming-phase-only in this mode and inert once the block is a card
2998
+ * (there is nothing to toggle or copy on a collapsed card). Blocks that are
2999
+ * already complete when they first render (page-refresh hydration) render
3000
+ * the card directly, with no flash of the inline body and no animation.
3001
+ *
3002
+ * Default `"inline"`.
3003
+ */
3004
+ completeDisplay?: "inline" | "card";
3005
+ };
3006
+ /**
3007
+ * Called when an artifact action is triggered (open, download, expand).
3008
+ * Return `true` to intercept: the widget then does not change state.
3009
+ * For `expand`, `expanded` is the state the toggle is about to enter and
3010
+ * `artifactId` is the currently selected artifact (or `null` when none).
2360
3011
  */
2361
3012
  onArtifactAction?: (action: {
2362
3013
  type: 'open' | 'download';
2363
3014
  artifactId: string;
3015
+ } | {
3016
+ type: 'expand';
3017
+ artifactId: string | null;
3018
+ expanded: boolean;
2364
3019
  }) => boolean | void;
2365
3020
  /**
2366
3021
  * Custom renderer for artifact reference cards shown in the message thread.
@@ -2376,6 +3031,72 @@ type AgentWidgetArtifactsFeature = {
2376
3031
  config: AgentWidgetConfig;
2377
3032
  defaultRenderer: () => HTMLElement;
2378
3033
  }) => HTMLElement | null;
3034
+ /**
3035
+ * Custom renderer for inline artifact blocks (display: "inline"), mirroring
3036
+ * `renderCard`. Return an element to replace the default inline preview,
3037
+ * or null to use the default.
3038
+ */
3039
+ renderInline?: (context: {
3040
+ artifact: {
3041
+ artifactId: string;
3042
+ title: string;
3043
+ artifactType: string;
3044
+ status: string;
3045
+ };
3046
+ config: AgentWidgetConfig;
3047
+ defaultRenderer: () => HTMLElement;
3048
+ }) => HTMLElement | null;
3049
+ /**
3050
+ * Text shown while an artifact streams, in place of the default
3051
+ * `Generating <type>...` status. Applies to every streaming surface: the
3052
+ * reference card status line, the inline chrome meta label, and the inline
3053
+ * streaming status body (`inlineBody.streamingView: "status"`).
3054
+ *
3055
+ * - A plain string replaces the default label everywhere (localization or
3056
+ * brand voice).
3057
+ * - A function is called on every artifact update for each visible surface;
3058
+ * it must be pure and fast. Returning a string sets the animated label
3059
+ * only. Returning `{ label, detail }` splits the status into an animated
3060
+ * label (re-applied only when its text changes, so the loading animation
3061
+ * stays stable) and a plain un-animated detail span that may update freely
3062
+ * per delta (live counters).
3063
+ *
3064
+ * Default when unset: the current behavior, `Generating <type>...` with no
3065
+ * detail. If the function throws, the default label is used for that update
3066
+ * (a bad host callback must never break rendering). There is deliberately no
3067
+ * percent progress: streams do not announce total length, so counts and
3068
+ * elapsed time are the only truthful signals.
3069
+ */
3070
+ statusLabel?: string | ((ctx: PersonaArtifactStatusLabelContext) => string | {
3071
+ label: string;
3072
+ detail?: string;
3073
+ });
3074
+ /**
3075
+ * Animation applied to the artifact card's "Generating …" status text while
3076
+ * the artifact streams. Character-by-character modes (`shimmer`,
3077
+ * `shimmer-color`, `rainbow`) wrap each character in a span with a staggered
3078
+ * `animation-delay`; `pulse` fades the whole status text; `none` disables the
3079
+ * animation. Honors `prefers-reduced-motion`.
3080
+ * @default "shimmer"
3081
+ */
3082
+ loadingAnimation?: AgentWidgetToolCallLoadingAnimation;
3083
+ /**
3084
+ * Duration of one full animation cycle in milliseconds.
3085
+ * Applies to pulse, shimmer, shimmer-color, and rainbow modes.
3086
+ * @default 2000
3087
+ */
3088
+ loadingAnimationDuration?: number;
3089
+ /**
3090
+ * Primary color for shimmer-color animation mode.
3091
+ * Defaults to the current text color.
3092
+ */
3093
+ loadingAnimationColor?: string;
3094
+ /**
3095
+ * Secondary/end color for shimmer-color animation mode.
3096
+ * Creates a gradient sweep between `loadingAnimationColor` and this color.
3097
+ * @default "#3b82f6"
3098
+ */
3099
+ loadingAnimationSecondaryColor?: string;
2379
3100
  };
2380
3101
  /**
2381
3102
  * How the transcript scrolls while an assistant response streams in.
@@ -2503,6 +3224,13 @@ type AgentWidgetToolCallDisplayFeature = {
2503
3224
  * @default false
2504
3225
  */
2505
3226
  grouped?: boolean;
3227
+ /**
3228
+ * Controls how a grouped tool sequence is rendered.
3229
+ * - `"stack"`: show the group summary and each child tool row.
3230
+ * - `"summary"`: show one consolidated summary row only.
3231
+ * @default "stack"
3232
+ */
3233
+ groupedMode?: "stack" | "summary";
2506
3234
  /**
2507
3235
  * When false, tool call bubbles show only the collapsed summary with no
2508
3236
  * expand/collapse toggle. Users see tool awareness without full details.
@@ -3192,6 +3920,24 @@ type AgentWidgetLauncherConfig = {
3192
3920
  * @default false
3193
3921
  */
3194
3922
  sidebarMode?: boolean;
3923
+ /**
3924
+ * When true, the widget panel renders as a detached card inset within its region,
3925
+ * with rounded corners on all sides and elevation (shadow plus hairline border),
3926
+ * instead of sitting flush against the region edges.
3927
+ *
3928
+ * The gap around the card is themed via `theme.components.panel.inset`. The
3929
+ * background revealed behind it is themed via `theme.components.panel.canvasBackground`
3930
+ * in docked and inline embed modes. In sidebar mode the gap stays click-through, so the
3931
+ * host page shows through it the same way it does in floating mode, and canvasBackground
3932
+ * is a no-op there.
3933
+ *
3934
+ * Applies to sidebar, docked, and inline embed modes. Ignored in mobile fullscreen,
3935
+ * where chrome is already suppressed. Floating mode is unchanged, since it already
3936
+ * renders as a detached card.
3937
+ *
3938
+ * @default false
3939
+ */
3940
+ detachedPanel?: boolean;
3195
3941
  /**
3196
3942
  * Width of the sidebar panel when sidebarMode is true.
3197
3943
  * @default "420px"
@@ -6098,6 +6844,21 @@ type InjectComponentDirectiveOptions = {
6098
6844
  */
6099
6845
  sequence?: number;
6100
6846
  };
6847
+ /**
6848
+ * Optional file metadata attached to a markdown artifact that represents a
6849
+ * concrete file written by a Claude Managed agent (e.g. `/mnt/session/outputs/cat.html`).
6850
+ * Additive: the artifact content stays a fenced code block on the wire for
6851
+ * backward compatibility; new widgets use this to recover the raw source and
6852
+ * offer a preview. Mirrors the `file` field on the core `artifact_start` event.
6853
+ */
6854
+ type PersonaArtifactFileMeta = {
6855
+ /** Full path of the written file (also used as the artifact title). */
6856
+ path: string;
6857
+ /** MIME type of the file (used for download and preview decisions). */
6858
+ mimeType: string;
6859
+ /** Fence language the content was encoded with (html/xml/md/text). */
6860
+ language?: string;
6861
+ };
6101
6862
  type PersonaArtifactRecord = {
6102
6863
  id: string;
6103
6864
  artifactType: PersonaArtifactKind;
@@ -6106,6 +6867,8 @@ type PersonaArtifactRecord = {
6106
6867
  markdown?: string;
6107
6868
  component?: string;
6108
6869
  props?: Record<string, unknown>;
6870
+ /** Present when this markdown artifact is a previewable file (see PersonaArtifactFileMeta). */
6871
+ file?: PersonaArtifactFileMeta;
6109
6872
  };
6110
6873
  /** Programmatic artifact upsert (controller / window API) */
6111
6874
  type PersonaArtifactManualUpsert = {
@@ -6113,12 +6876,18 @@ type PersonaArtifactManualUpsert = {
6113
6876
  artifactType: "markdown";
6114
6877
  title?: string;
6115
6878
  content: string;
6879
+ /** Optional file metadata for previewable file artifacts. */
6880
+ file?: PersonaArtifactFileMeta;
6881
+ /** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
6882
+ transcript?: boolean;
6116
6883
  } | {
6117
6884
  id?: string;
6118
6885
  artifactType: "component";
6119
6886
  title?: string;
6120
6887
  component: string;
6121
6888
  props?: Record<string, unknown>;
6889
+ /** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
6890
+ transcript?: boolean;
6122
6891
  };
6123
6892
  type AgentWidgetEvent = {
6124
6893
  type: "message";
@@ -6153,6 +6922,8 @@ type AgentWidgetEvent = {
6153
6922
  artifactType: PersonaArtifactKind;
6154
6923
  title?: string;
6155
6924
  component?: string;
6925
+ /** Present when this markdown artifact is a previewable file. */
6926
+ file?: PersonaArtifactFileMeta;
6156
6927
  } | {
6157
6928
  type: "artifact_delta";
6158
6929
  id: string;
@@ -6200,6 +6971,7 @@ declare class AgentWidgetClient {
6200
6971
  private sessionInitPromise;
6201
6972
  private lastSentClientToolsFingerprint;
6202
6973
  private clientToolsFingerprintSessionId;
6974
+ private sentNonEmptyClientToolsSessionId;
6203
6975
  private readonly webMcpBridge;
6204
6976
  constructor(config?: AgentWidgetConfig);
6205
6977
  /**
@@ -6395,8 +7167,13 @@ declare class AgentWidgetClient {
6395
7167
  * - **client-token mode**: POST `${apiBase}/v1/client/resume` (the
6396
7168
  * session-authenticated sibling of `/v1/client/chat`; runtypelabs/core#3889),
6397
7169
  * with the active `sessionId` in the body and no Bearer key: a browser
6398
- * client-token page holds no secret. `clientTools` are already persisted
6399
- * server-side from the dispatch turn, so only `toolOutputs` is re-sent.
7170
+ * client-token page holds no secret. The page's tool registry is
7171
+ * re-snapshotted and sent alongside `toolOutputs` via the same diff-only
7172
+ * `clientTools` / `clientToolsFingerprint` protocol as `/v1/client/chat`
7173
+ * (runtypelabs/core#5361), so tools registered by a mid-run page
7174
+ * navigation replace the run's dispatch-time set and become callable on
7175
+ * the next model turn. Old servers strip the unknown fields and keep the
7176
+ * frozen-at-dispatch behavior.
6400
7177
  * - **dispatch / proxy mode**: POST `${apiUrl}/resume`: Runtype mounts
6401
7178
  * resume as a child of `/v1/dispatch`, so the URL is `${apiUrl}/resume`,
6402
7179
  * and proxies follow the same shape (`/api/chat/dispatch/resume`).
@@ -6408,6 +7185,39 @@ declare class AgentWidgetClient {
6408
7185
  * @param toolOutputs - Map keyed by per-call `toolCallId` (core#3878),
6409
7186
  * falling back to tool name for legacy servers → the tool's result value.
6410
7187
  */
7188
+ /**
7189
+ * Diff-only / send-once WebMCP clientTools transport, shared by the
7190
+ * client-token chat (`/v1/client/chat`) and resume (`/v1/client/resume`)
7191
+ * paths — both routes speak the same protocol (runtypelabs/core#5361).
7192
+ *
7193
+ * Decides, against the shared fingerprint cache, whether this request ships
7194
+ * the full `clientTools[]` + fingerprint (first send under this session, or
7195
+ * a changed set) or the fingerprint alone (unchanged set; the server reuses
7196
+ * its stored copy). Runs `doFetch` with the chosen fields and retries
7197
+ * EXACTLY once with the full array on a
7198
+ * `409 { error: 'client_tools_resend_required' }` registry miss — the retry
7199
+ * is 409-*triggered*, never 409-*expected*, so servers predating the
7200
+ * protocol (which strip the unknown fields and never 409) work unchanged.
7201
+ * The 409 body is probed on a `clone()` so the original response body stays
7202
+ * readable by the caller's error handling.
7203
+ *
7204
+ * The cache is NOT committed here: callers invoke the returned `commit()`
7205
+ * only after the server has accepted the request (response OK / stream
7206
+ * started), so a failed request can never record a fingerprint the server
7207
+ * never stored. A resend-required miss invalidates the cached fingerprint
7208
+ * immediately so later turns keep resending in full until a clean success
7209
+ * commits a fresh one.
7210
+ *
7211
+ * `emptyMeansReplace` (resume only): when the live snapshot is empty but a
7212
+ * non-empty set was committed under this session and never explicitly
7213
+ * cleared (the paused tool navigated to a page with no tool registry), ship
7214
+ * an explicit `clientTools: []` so the server REPLACES the persisted
7215
+ * dispatch-time set with nothing and clears its stored registry. Chat keeps
7216
+ * its omit-when-empty behavior: on `/chat`, absent fields already mean "no
7217
+ * tools this turn", whereas on `/resume` absence means "keep the frozen
7218
+ * dispatch-time set".
7219
+ */
7220
+ private sendWithClientToolsDiff;
6411
7221
  resumeFlow(executionId: string, toolOutputs: Record<string, unknown>, options?: {
6412
7222
  streamResponse?: boolean;
6413
7223
  signal?: AbortSignal;
@@ -6992,6 +7802,23 @@ declare class AgentWidgetSession {
6992
7802
  selectArtifact(id: string | null): void;
6993
7803
  clearArtifacts(): void;
6994
7804
  upsertArtifact(manual: PersonaArtifactManualUpsert): PersonaArtifactRecord;
7805
+ /**
7806
+ * Injects (or refreshes) the in-thread artifact block for a programmatically
7807
+ * upserted artifact, matching the streamed UX: the resolved display mode
7808
+ * picks the component ("card"/"panel" → reference card, "inline" → inline
7809
+ * preview).
7810
+ *
7811
+ * Unlike the streamed path (which embeds content on `artifact_complete`),
7812
+ * the programmatic record is complete up front, so the final markdown /
7813
+ * file meta / component name + props are embedded immediately and the block
7814
+ * hydrates after a refresh without the original registry state.
7815
+ *
7816
+ * A re-upsert of the same id rebuilds the existing block's persisted
7817
+ * rawContent in place (the registry is not persisted, so hydration reads
7818
+ * these props); without this the block would keep the first version's
7819
+ * content after a refresh.
7820
+ */
7821
+ private injectArtifactRefBlock;
6995
7822
  private clearArtifactState;
6996
7823
  private emitArtifactsState;
6997
7824
  private applyArtifactStreamEvent;
@@ -7771,6 +8598,32 @@ declare const createDirectivePostprocessor: (markdownConfig?: AgentWidgetMarkdow
7771
8598
  */
7772
8599
  declare const directivePostprocessor: (text: string) => string;
7773
8600
 
8601
+ type MarkdownParsersModule = {
8602
+ Marked: typeof Marked;
8603
+ DOMPurify: typeof DOMPurify;
8604
+ };
8605
+ /**
8606
+ * Register `cb` to run once the markdown parsers (marked + DOMPurify) become
8607
+ * available, i.e. when the lazy `markdown-parsers.js` chunk resolves on the
8608
+ * IIFE/CDN build. Returns an unsubscribe function.
8609
+ *
8610
+ * This exists so every markdown render surface (chat messages, artifact pane,
8611
+ * and any future one) shares a SINGLE self-heal path instead of each wiring its
8612
+ * own `loadMarkdownParsers().then(reRender)`. Before this, a new surface that
8613
+ * forgot to do that rendered escaped plain text until a user interaction forced
8614
+ * a re-render — the recurring first-render bug (chat messages, then the artifact
8615
+ * pane) this centralizes away.
8616
+ *
8617
+ * If the parsers are ALREADY loaded, `cb` is not scheduled and a no-op
8618
+ * unsubscribe is returned: the caller's first render already used real markdown,
8619
+ * so there is nothing to heal (this is the ESM/CJS build's steady state, and the
8620
+ * CDN build's state after the first chunk load). Registering also kicks the load
8621
+ * so a surface that renders before anything else triggers it still heals.
8622
+ * Fires at most once per subscription.
8623
+ */
8624
+ declare const onMarkdownParsersReady: (cb: () => void) => (() => void);
8625
+ declare const loadMarkdownParsers: () => Promise<MarkdownParsersModule>;
8626
+
7774
8627
  /**
7775
8628
  * A function that sanitizes an HTML string, returning safe HTML.
7776
8629
  */
@@ -8237,161 +9090,6 @@ interface DropdownMenuHandle {
8237
9090
  */
8238
9091
  declare function createDropdownMenu(options: CreateDropdownOptions): DropdownMenuHandle;
8239
9092
 
8240
- /**
8241
- * Curated registry of lucide icons available to `renderLucideIcon`.
8242
- *
8243
- * The widget used to do `import * as icons from "lucide"` and look up
8244
- * icons dynamically by string. That defeated tree-shaking, so the IIFE
8245
- * (CDN/script-tag) bundle shipped all 1640 lucide icons (~400KB of icon
8246
- * data) regardless of which we actually used. This explicit registry
8247
- * lets the bundler drop any icon not listed here.
8248
- *
8249
- * Trade-off: `renderLucideIcon(name)` is now a *closed set*. Names not
8250
- * in this map return `null` and log a warning, exactly as a typo did
8251
- * before. The registry is intentionally generous (~110 icons) so that
8252
- * custom `ComponentRenderer` authors rarely hit a missing-icon dead end.
8253
- *
8254
- * To add icons: add a named import above and a row in `LUCIDE_ICONS`,
8255
- * keyed by the lucide kebab-case name (matches their filename and
8256
- * https://lucide.dev/icons).
8257
- *
8258
- * See `packages/widget/docs/icon-registry-shortlist.md` for the full
8259
- * curation rationale and which icons were considered but excluded.
8260
- */
8261
- declare const LUCIDE_ICONS: {
8262
- readonly activity: IconNode;
8263
- readonly "arrow-down": IconNode;
8264
- readonly "arrow-up": IconNode;
8265
- readonly "arrow-up-right": IconNode;
8266
- readonly bot: IconNode;
8267
- readonly "chevron-down": IconNode;
8268
- readonly "chevron-up": IconNode;
8269
- readonly "chevron-right": IconNode;
8270
- readonly "chevron-left": IconNode;
8271
- readonly check: IconNode;
8272
- readonly clipboard: IconNode;
8273
- readonly "clipboard-copy": IconNode;
8274
- readonly copy: IconNode;
8275
- readonly file: IconNode;
8276
- readonly "file-code": IconNode;
8277
- readonly "file-spreadsheet": IconNode;
8278
- readonly "file-text": IconNode;
8279
- readonly "image-plus": IconNode;
8280
- readonly loader: IconNode;
8281
- readonly "loader-circle": IconNode;
8282
- readonly mic: IconNode;
8283
- readonly paperclip: IconNode;
8284
- readonly "refresh-cw": IconNode;
8285
- readonly search: IconNode;
8286
- readonly send: IconNode;
8287
- readonly "shield-alert": IconNode;
8288
- readonly "shield-check": IconNode;
8289
- readonly "shield-x": IconNode;
8290
- readonly square: IconNode;
8291
- readonly "thumbs-down": IconNode;
8292
- readonly "thumbs-up": IconNode;
8293
- readonly upload: IconNode;
8294
- readonly "volume-2": IconNode;
8295
- readonly x: IconNode;
8296
- readonly user: IconNode;
8297
- readonly mail: IconNode;
8298
- readonly phone: IconNode;
8299
- readonly calendar: IconNode;
8300
- readonly clock: IconNode;
8301
- readonly building: IconNode;
8302
- readonly "map-pin": IconNode;
8303
- readonly lock: IconNode;
8304
- readonly key: IconNode;
8305
- readonly "credit-card": IconNode;
8306
- readonly "at-sign": IconNode;
8307
- readonly hash: IconNode;
8308
- readonly globe: IconNode;
8309
- readonly link: IconNode;
8310
- readonly "circle-check": IconNode;
8311
- readonly "circle-x": IconNode;
8312
- readonly "triangle-alert": IconNode;
8313
- readonly info: IconNode;
8314
- readonly ban: IconNode;
8315
- readonly shield: IconNode;
8316
- readonly "arrow-left": IconNode;
8317
- readonly "arrow-right": IconNode;
8318
- readonly "external-link": IconNode;
8319
- readonly ellipsis: IconNode;
8320
- readonly "ellipsis-vertical": IconNode;
8321
- readonly menu: IconNode;
8322
- readonly house: IconNode;
8323
- readonly plus: IconNode;
8324
- readonly minus: IconNode;
8325
- readonly pencil: IconNode;
8326
- readonly trash: IconNode;
8327
- readonly "trash-2": IconNode;
8328
- readonly save: IconNode;
8329
- readonly download: IconNode;
8330
- readonly share: IconNode;
8331
- readonly funnel: IconNode;
8332
- readonly settings: IconNode;
8333
- readonly "rotate-cw": IconNode;
8334
- readonly maximize: IconNode;
8335
- readonly minimize: IconNode;
8336
- readonly "shopping-cart": IconNode;
8337
- readonly "shopping-bag": IconNode;
8338
- readonly package: IconNode;
8339
- readonly truck: IconNode;
8340
- readonly tag: IconNode;
8341
- readonly gift: IconNode;
8342
- readonly receipt: IconNode;
8343
- readonly wallet: IconNode;
8344
- readonly store: IconNode;
8345
- readonly "dollar-sign": IconNode;
8346
- readonly percent: IconNode;
8347
- readonly play: IconNode;
8348
- readonly pause: IconNode;
8349
- readonly "volume-x": IconNode;
8350
- readonly camera: IconNode;
8351
- readonly image: IconNode;
8352
- readonly film: IconNode;
8353
- readonly headphones: IconNode;
8354
- readonly "message-circle": IconNode;
8355
- readonly "message-square": IconNode;
8356
- readonly bell: IconNode;
8357
- readonly heart: IconNode;
8358
- readonly star: IconNode;
8359
- readonly eye: IconNode;
8360
- readonly "eye-off": IconNode;
8361
- readonly bookmark: IconNode;
8362
- readonly "calendar-days": IconNode;
8363
- readonly history: IconNode;
8364
- readonly timer: IconNode;
8365
- readonly folder: IconNode;
8366
- readonly "folder-open": IconNode;
8367
- readonly files: IconNode;
8368
- readonly sparkles: IconNode;
8369
- readonly zap: IconNode;
8370
- readonly sun: IconNode;
8371
- readonly moon: IconNode;
8372
- readonly flag: IconNode;
8373
- readonly monitor: IconNode;
8374
- readonly smartphone: IconNode;
8375
- };
8376
- /**
8377
- * Names of lucide icons that ship with the widget. Names not in this
8378
- * union return `null` from `renderLucideIcon` (with a console warning).
8379
- */
8380
- type IconName = keyof typeof LUCIDE_ICONS;
8381
- /**
8382
- * Renders a lucide icon as an inline SVG element. Works inside Shadow
8383
- * DOM and requires no CSS.
8384
- *
8385
- * @param iconName - A lucide kebab-case name from the registry. See
8386
- * `IconName` for the full list, or `docs/icon-registry-shortlist.md`
8387
- * for rationale.
8388
- * @param size - The size in pixels (number) or any CSS length string.
8389
- * @param color - Stroke color (default: "currentColor").
8390
- * @param strokeWidth - Stroke width (default: 2).
8391
- * @returns SVGElement, or null if the name is not in the registry.
8392
- */
8393
- declare const renderLucideIcon: (iconName: IconName | (string & {}), size?: number | string, color?: string, strokeWidth?: number) => SVGElement | null;
8394
-
8395
9093
  /** Options for {@link createIconButton}. */
8396
9094
  interface CreateIconButtonOptions {
8397
9095
  /** Lucide icon name (kebab-case, e.g. "eye", "chevron-down"). */
@@ -8449,6 +9147,8 @@ interface ToggleGroupItem {
8449
9147
  icon?: string;
8450
9148
  /** Accessible label for the button. */
8451
9149
  label: string;
9150
+ /** Extra CSS class(es) appended after "persona-icon-btn". */
9151
+ className?: string;
8452
9152
  }
8453
9153
  /** Options for {@link createToggleGroup}. */
8454
9154
  interface CreateToggleGroupOptions {
@@ -8736,6 +9436,8 @@ declare const THEME_ZONES: {
8736
9436
  readonly container: "Main widget container";
8737
9437
  readonly 'artifact-pane': "Artifact sidebar";
8738
9438
  readonly 'artifact-toolbar': "Artifact toolbar";
9439
+ readonly 'artifact-inline': "Inline artifact block";
9440
+ readonly 'artifact-inline-chrome': "Inline artifact title bar";
8739
9441
  };
8740
9442
  type ThemeZone = keyof typeof THEME_ZONES;
8741
9443
 
@@ -8787,15 +9489,27 @@ interface ComponentContext {
8787
9489
  * Component renderer function signature
8788
9490
  */
8789
9491
  type ComponentRenderer = (props: Record<string, unknown>, context: ComponentContext) => HTMLElement;
9492
+ /**
9493
+ * Per-component registration options
9494
+ */
9495
+ interface ComponentRegistrationOptions {
9496
+ /**
9497
+ * When false, the component directive renders bare in the thread (no
9498
+ * persona-message-bubble chrome).
9499
+ * @default true
9500
+ */
9501
+ bubbleChrome?: boolean;
9502
+ }
8790
9503
  /**
8791
9504
  * Component registry for managing custom components
8792
9505
  */
8793
9506
  declare class ComponentRegistry {
8794
9507
  private components;
9508
+ private options;
8795
9509
  /**
8796
9510
  * Register a custom component
8797
9511
  */
8798
- register(name: string, renderer: ComponentRenderer): void;
9512
+ register(name: string, renderer: ComponentRenderer, options?: ComponentRegistrationOptions): void;
8799
9513
  /**
8800
9514
  * Unregister a component
8801
9515
  */
@@ -8808,6 +9522,10 @@ declare class ComponentRegistry {
8808
9522
  * Check if a component is registered
8809
9523
  */
8810
9524
  has(name: string): boolean;
9525
+ /**
9526
+ * Get the registration options for a component, if any were supplied
9527
+ */
9528
+ getOptions(name: string): ComponentRegistrationOptions | undefined;
8811
9529
  /**
8812
9530
  * Get all registered component names
8813
9531
  */
@@ -9249,4 +9967,30 @@ interface DemoCarouselHandle {
9249
9967
  }
9250
9968
  declare function createDemoCarousel(container: HTMLElement, options: DemoCarouselOptions): DemoCarouselHandle;
9251
9969
 
9252
- export { ASK_USER_QUESTION_CLIENT_TOOL, ASK_USER_QUESTION_PARAMETERS_SCHEMA, ASK_USER_QUESTION_TOOL_NAME, type AgentConfig, type AgentExecutionState, type AgentLoopConfig, type AgentMessageMetadata, type AgentRequestOptions, type AgentToolsConfig, type AgentWidgetActionContext, type AgentWidgetActionEventPayload, type AgentWidgetActionHandler, type AgentWidgetActionHandlerResult, type AgentWidgetActionParser, type AgentWidgetAgentRequestPayload, type AgentWidgetApproval, type AgentWidgetApprovalConfig, type AgentWidgetApprovalDecisionOptions, type AgentWidgetArtifactsFeature, type AgentWidgetArtifactsLayoutConfig, type AgentWidgetAskUserQuestionFeature, type AgentWidgetAskUserQuestionStyles, type AgentWidgetAttachmentsConfig, type AgentWidgetAvatarConfig, AgentWidgetClient, type AgentWidgetComponentRenderer, type AgentWidgetComposerConfig, type AgentWidgetConfig, type AgentWidgetContextProvider, type AgentWidgetContextProviderContext, type AgentWidgetController, type AgentWidgetControllerEventMap, type AgentWidgetCustomFetch, type AgentWidgetDockConfig, type AgentWidgetEvent, type AgentWidgetFeatureFlags, type AgentWidgetHeaderLayoutConfig, type AgentWidgetHeadersFunction, type AgentWidgetInitHandle, type AgentWidgetInitOptions, type AgentWidgetLauncherConfig, type AgentWidgetLayoutConfig, type AgentWidgetLoadingIndicatorConfig, type AgentWidgetMarkdownConfig, type AgentWidgetMarkdownOptions, type AgentWidgetMarkdownRendererOverrides, type AgentWidgetMessage, type AgentWidgetMessageActionsConfig, type AgentWidgetMessageFeedback, type AgentWidgetMessageLayoutConfig, type AgentWidgetParsedAction, type AgentWidgetPlugin, type AgentWidgetReadAloudEvent, type AgentWidgetRequestPayload, type AgentWidgetSSEEventParser, type AgentWidgetSSEEventResult, type AgentWidgetScrollBehaviorFeature, type AgentWidgetScrollMode, type AgentWidgetScrollRestorePosition, type AgentWidgetScrollToBottomFeature, AgentWidgetSession, type AgentWidgetSessionStatus, type AgentWidgetStreamAnimationBuffer, type AgentWidgetStreamAnimationBuiltinType, type AgentWidgetStreamAnimationFeature, type AgentWidgetStreamAnimationPlaceholder, type AgentWidgetStreamAnimationType, type AgentWidgetStreamParser, type AgentWidgetStreamParserResult, type AgentWidgetTimestampConfig, type AgentWidgetVoiceStatusEvent, type AgentWidgetWebMcpConfig, type ArtifactConfigPayload, type ArtifactPaneTokens, type ArtifactTabTokens, type ArtifactToolbarTokens, type AskUserQuestionOption, type AskUserQuestionPayload, type AskUserQuestionPrompt, AttachmentManager, type AttachmentManagerConfig, type BorderScale, BrowserSpeechEngine, type BrowserSpeechEngineOptions, type CSATFeedbackOptions, type ClientChatRequest, type ClientFeedbackRequest, type ClientFeedbackType, type ClientInitResponse, type ClientSession, type ClientToolDefinition, type CodeFormat, type CodeGeneratorHooks, type CodeGeneratorOptions, type ColorPalette, type ColorShade, type ComboButtonHandle, type ComponentContext, type ComponentDirective, type ComponentRenderer, type ComponentTokens, type ComposerBuildContext, type ComposerElements, type ContentPart, type CreateComboButtonOptions, type CreateDropdownOptions, type CreateIconButtonOptions, type CreateLabelButtonOptions, type CreateStandardBubbleOptions, type CreateThemeOptions, type CreateToggleGroupOptions, DEFAULT_COMPONENTS, DEFAULT_FLOATING_LAUNCHER_MAX_WIDTH, DEFAULT_FLOATING_LAUNCHER_WIDTH, DEFAULT_PALETTE, DEFAULT_SEMANTIC, DEFAULT_WIDGET_CONFIG, type DeepPartial, type DemoCarouselHandle, type DemoCarouselItem, type DemoCarouselOptions, type DomContextMode, type DomContextOptions, type DropdownMenuHandle, type DropdownMenuItem, type EnrichedPageElement, type EventStreamBadgeColor, type EventStreamConfig, type EventStreamPayloadRenderContext, type EventStreamRowRenderContext, type EventStreamToolbarRenderContext, type EventStreamViewRenderContext, type FallbackSpeechEngineOptions, type FormatEnrichedContextOptions, type HeaderBuildContext, type HeaderElements, type HeaderLayoutContext, type HeaderLayoutRenderer, type HeaderRenderContext, type IconButtonTokens, type IconName, type IdleIndicatorRenderContext, type ImageContentPart, type InjectAssistantMessageOptions, type InjectComponentDirectiveOptions, type InjectMessageOptions, type InjectSystemMessageOptions, type InjectUserMessageOptions, type LabelButtonTokens, type LoadingIndicatorRenderContext, type LoadingIndicatorRenderer, type MarkdownProcessorOptions, type MessageActionCallbacks, type MessageContent, type MessageRenderContext, type MessageTransform, type NPSFeedbackOptions, PRESETS, PRESET_FULLSCREEN, PRESET_MINIMAL, PRESET_SHOP, type ParseOptionsConfig, type ParseRule, type PcmStreamPlayer, type PendingAttachment, type PersonaArtifactKind, type PersonaArtifactManualUpsert, type PersonaArtifactRecord, type PersonaTheme, type PersonaThemePlugin, type RadiusScale, ReadAloudController, type ReadAloudListener, type ReadAloudState, type ResolvedTarget, type RuleScoringContext, type RuntypeClientChatRequest, type RuntypeClientChatStreamEvent, type RuntypeClientFeedbackRequest, type RuntypeClientFeedbackResponse, type RuntypeClientFeedbackType, type RuntypeClientInitRequest, type RuntypeClientInitResponse, type RuntypeClientResumeRequest, type RuntypeClientResumeStreamEvent, type RuntypeExecutionStreamEvent, type RuntypeFlowSSEEvent, type RuntypeStepCompleteEvent, type RuntypeStopReasonKind, type RuntypeStreamEventOf, type RuntypeTurnCompleteEvent, type SSEEventCallback, type SSEEventRecord, SUGGEST_REPLIES_CLIENT_TOOL, SUGGEST_REPLIES_PARAMETERS_SCHEMA, SUGGEST_REPLIES_TOOL_NAME, type SanitizeFunction, type SemanticColors, type SemanticSpacing, type SemanticTypography, type ShadowScale, type SlotRenderContext, type SlotRenderer, type SpacingScale, type SpeechCallbacks, type SpeechEngine, type SpeechRequest, type StreamAnimationContext, type StreamAnimationPlugin, THEME_ZONES, type TargetResolver, type TextContentPart, type ThemeValidationError, type ThemeValidationResult, type ThemeZone, type ToggleGroupHandle, type ToggleGroupItem, type ToggleGroupTokens, type TokenReference, type TypographyScale, VERSION, type VoiceConfig, type VoiceMetrics, type VoicePlaybackEngine, type VoiceProvider, type VoiceResult, type VoiceStatus, WEBMCP_TOOL_PREFIX, WebMcpBridge, type WebMcpConfirmHandler, type WebMcpConfirmInfo, type WebMcpToolResult, type WidgetHostLayout, type WidgetHostLayoutMode, type WidgetLayoutSlot, type WidgetPreset, accessibilityPlugin, animationsPlugin, applyThemeVariables, attachHeaderToContainer, brandPlugin, buildComposer, buildDefaultHeader, buildHeader, buildHeaderWithLayout, buildMinimalHeader, builtInClientToolsForDispatch, collectEnrichedPageContext, componentRegistry, createActionManager, createAgentExperience, createAskUserQuestionBubble, createBestAvailableVoiceProvider, createBubbleWithLayout, createCSATFeedback, createComboButton, createComponentMiddleware, createComponentStreamParser, createDefaultSanitizer, createDemoCarousel, createDirectivePostprocessor, createDropdownMenu, createFlexibleJsonStreamParser, createIconButton, createImagePart, createJsonStreamParser, createLabelButton, createLocalStorageAdapter, createMarkdownProcessor, createMarkdownProcessorFromConfig, createMessageActions, createNPSFeedback, createPlainTextParser, createPlugin, createRegexJsonParser, createStandardBubble, createTextPart, createTheme, createThemeObserver, createToggleGroup, createTypingIndicator, createVoiceProvider, createWidgetHostLayout, createXmlParser, initAgentWidget as default, defaultActionHandlers, defaultJsonActionParser, defaultParseRules, detectColorScheme, directivePostprocessor, ensureAskUserQuestionSheet, escapeHtml, extractComponentDirectiveFromMessage, fileToImagePart, formatEnrichedContext, generateAssistantMessageId, generateCodeSnippet, generateMessageId, generateStableSelector, generateUserMessageId, getActiveTheme, getColorScheme, getDisplayText, getHeaderLayout, getImageParts, getPreset, hasComponentDirective, hasImages, headerLayouts, highContrastPlugin, initAgentWidget, isAskUserQuestionMessage, isComponentDirectiveType, isDockedMountMode, isSuggestRepliesMessage, isVoiceSupported, isWebMcpToolName, latestAgentSuggestions, listRegisteredStreamAnimations, markdownPostprocessor, mergeWithDefaults, normalizeContent, parseAskUserQuestionPayload, parseSuggestRepliesPayload, pickBestVoice, pluginRegistry, reducedMotionPlugin, registerStreamAnimationPlugin, removeAskUserQuestionSheet, renderComponentDirective, renderLoadingIndicatorWithFallback, renderLucideIcon, resolveDockConfig, resolveSanitizer, resolveTokens, stripWebMcpPrefix, themeToCssVariables, unregisterStreamAnimationPlugin, validateImageFile, validateTheme };
9970
+ /**
9971
+ * Roving-tabindex tablist controller (WAI-ARIA APG tabs pattern). Owns the tab
9972
+ * roles, aria-selected, roving tabindex, Arrow/Home/End keyboard nav routed
9973
+ * through an onSelect callback, focus reveal via scrollIntoView, and focus
9974
+ * survival across a tab-DOM rebuild. Extracted so custom tab bars stay
9975
+ * accessible without re-implementing the pattern.
9976
+ */
9977
+ interface RovingTablistOptions {
9978
+ onSelect: (index: number) => void;
9979
+ /** Arrow-key axis. @default "horizontal" */
9980
+ orientation?: "horizontal" | "vertical";
9981
+ }
9982
+ interface RovingTablistController {
9983
+ /** Snapshot whether focus is inside the strip. Call before replacing tab DOM. */
9984
+ beforeRender(): void;
9985
+ /**
9986
+ * Apply role=tablist/tab, aria-selected, roving tabindex, and keyboard nav to
9987
+ * the given tab elements (in order). Restores focus to the selected tab when
9988
+ * the last beforeRender() saw focus inside the strip. Call after (re)building
9989
+ * tabs.
9990
+ */
9991
+ render(tabs: HTMLElement[], selectedIndex: number): void;
9992
+ destroy(): void;
9993
+ }
9994
+ declare function createRovingTablist(container: HTMLElement, options: RovingTablistOptions): RovingTablistController;
9995
+
9996
+ export { ASK_USER_QUESTION_CLIENT_TOOL, ASK_USER_QUESTION_PARAMETERS_SCHEMA, ASK_USER_QUESTION_TOOL_NAME, type AgentConfig, type AgentExecutionState, type AgentLoopConfig, type AgentMessageMetadata, type AgentRequestOptions, type AgentToolsConfig, type AgentWidgetActionContext, type AgentWidgetActionEventPayload, type AgentWidgetActionHandler, type AgentWidgetActionHandlerResult, type AgentWidgetActionParser, type AgentWidgetAgentRequestPayload, type AgentWidgetApproval, type AgentWidgetApprovalConfig, type AgentWidgetApprovalDecisionOptions, type AgentWidgetArtifactsFeature, type AgentWidgetArtifactsLayoutConfig, type AgentWidgetAskUserQuestionFeature, type AgentWidgetAskUserQuestionStyles, type AgentWidgetAttachmentsConfig, type AgentWidgetAvatarConfig, AgentWidgetClient, type AgentWidgetComponentRenderer, type AgentWidgetComposerConfig, type AgentWidgetConfig, type AgentWidgetContextProvider, type AgentWidgetContextProviderContext, type AgentWidgetController, type AgentWidgetControllerEventMap, type AgentWidgetCustomFetch, type AgentWidgetDockConfig, type AgentWidgetEvent, type AgentWidgetFeatureFlags, type AgentWidgetHeaderLayoutConfig, type AgentWidgetHeadersFunction, type AgentWidgetInitHandle, type AgentWidgetInitOptions, type AgentWidgetLauncherConfig, type AgentWidgetLayoutConfig, type AgentWidgetLoadingIndicatorConfig, type AgentWidgetMarkdownConfig, type AgentWidgetMarkdownOptions, type AgentWidgetMarkdownRendererOverrides, type AgentWidgetMessage, type AgentWidgetMessageActionsConfig, type AgentWidgetMessageFeedback, type AgentWidgetMessageLayoutConfig, type AgentWidgetParsedAction, type AgentWidgetPlugin, type AgentWidgetReadAloudEvent, type AgentWidgetRequestPayload, type AgentWidgetSSEEventParser, type AgentWidgetSSEEventResult, type AgentWidgetScrollBehaviorFeature, type AgentWidgetScrollMode, type AgentWidgetScrollRestorePosition, type AgentWidgetScrollToBottomFeature, AgentWidgetSession, type AgentWidgetSessionStatus, type AgentWidgetStreamAnimationBuffer, type AgentWidgetStreamAnimationBuiltinType, type AgentWidgetStreamAnimationFeature, type AgentWidgetStreamAnimationPlaceholder, type AgentWidgetStreamAnimationType, type AgentWidgetStreamParser, type AgentWidgetStreamParserResult, type AgentWidgetTimestampConfig, type AgentWidgetVoiceStatusEvent, type AgentWidgetWebMcpConfig, type ArtifactConfigPayload, type ArtifactPaneTokens, type ArtifactTabTokens, type ArtifactToolbarTokens, type AskUserQuestionOption, type AskUserQuestionPayload, type AskUserQuestionPrompt, AttachmentManager, type AttachmentManagerConfig, type BorderScale, BrowserSpeechEngine, type BrowserSpeechEngineOptions, type CSATFeedbackOptions, type ClientChatRequest, type ClientFeedbackRequest, type ClientFeedbackType, type ClientInitResponse, type ClientSession, type ClientToolDefinition, type CodeFormat, type CodeGeneratorHooks, type CodeGeneratorOptions, type ColorPalette, type ColorShade, type ComboButtonHandle, type ComponentContext, type ComponentDirective, type ComponentRegistrationOptions, type ComponentRenderer, type ComponentTokens, type ComposerBuildContext, type ComposerElements, type ContentPart, type CreateComboButtonOptions, type CreateDropdownOptions, type CreateIconButtonOptions, type CreateLabelButtonOptions, type CreateStandardBubbleOptions, type CreateThemeOptions, type CreateToggleGroupOptions, DEFAULT_COMPONENTS, DEFAULT_FLOATING_LAUNCHER_MAX_WIDTH, DEFAULT_FLOATING_LAUNCHER_WIDTH, DEFAULT_PALETTE, DEFAULT_SEMANTIC, DEFAULT_WIDGET_CONFIG, type DeepPartial, type DemoCarouselHandle, type DemoCarouselItem, type DemoCarouselOptions, type DomContextMode, type DomContextOptions, type DropdownMenuHandle, type DropdownMenuItem, type EnrichedPageElement, type EventStreamBadgeColor, type EventStreamConfig, type EventStreamPayloadRenderContext, type EventStreamRowRenderContext, type EventStreamToolbarRenderContext, type EventStreamViewRenderContext, type FallbackSpeechEngineOptions, type FormatEnrichedContextOptions, type HeaderBuildContext, type HeaderElements, type HeaderLayoutContext, type HeaderLayoutRenderer, type HeaderRenderContext, type IconButtonTokens, type IconName, type IdleIndicatorRenderContext, type ImageContentPart, type InjectAssistantMessageOptions, type InjectComponentDirectiveOptions, type InjectMessageOptions, type InjectSystemMessageOptions, type InjectUserMessageOptions, type LabelButtonTokens, type LoadingIndicatorRenderContext, type LoadingIndicatorRenderer, type MarkdownParsersModule, type MarkdownProcessorOptions, type MessageActionCallbacks, type MessageContent, type MessageRenderContext, type MessageTransform, type NPSFeedbackOptions, PRESETS, PRESET_FULLSCREEN, PRESET_MINIMAL, PRESET_SHOP, type ParseOptionsConfig, type ParseRule, type PcmStreamPlayer, type PendingAttachment, type PersonaArtifactActionContext, type PersonaArtifactCustomAction, type PersonaArtifactDisplayMode, type PersonaArtifactKind, type PersonaArtifactManualUpsert, type PersonaArtifactRecord, type PersonaArtifactStatusLabelContext, type PersonaTheme, type PersonaThemePlugin, type RadiusScale, ReadAloudController, type ReadAloudListener, type ReadAloudState, type ResolvedTarget, type RovingTablistController, type RovingTablistOptions, type RuleScoringContext, type RuntypeClientChatRequest, type RuntypeClientChatStreamEvent, type RuntypeClientFeedbackRequest, type RuntypeClientFeedbackResponse, type RuntypeClientFeedbackType, type RuntypeClientInitRequest, type RuntypeClientInitResponse, type RuntypeClientResumeRequest, type RuntypeClientResumeStreamEvent, type RuntypeExecutionStreamEvent, type RuntypeFlowSSEEvent, type RuntypeStepCompleteEvent, type RuntypeStopReasonKind, type RuntypeStreamEventOf, type RuntypeTurnCompleteEvent, type SSEEventCallback, type SSEEventRecord, SUGGEST_REPLIES_CLIENT_TOOL, SUGGEST_REPLIES_PARAMETERS_SCHEMA, SUGGEST_REPLIES_TOOL_NAME, type SanitizeFunction, type SemanticColors, type SemanticSpacing, type SemanticTypography, type ShadowScale, type SlotRenderContext, type SlotRenderer, type SpacingScale, type SpeechCallbacks, type SpeechEngine, type SpeechRequest, type StreamAnimationContext, type StreamAnimationPlugin, THEME_ZONES, type TargetResolver, type TextContentPart, type ThemeValidationError, type ThemeValidationResult, type ThemeZone, type ToggleGroupHandle, type ToggleGroupItem, type ToggleGroupTokens, type TokenReference, type TypographyScale, VERSION, type VoiceConfig, type VoiceMetrics, type VoicePlaybackEngine, type VoiceProvider, type VoiceResult, type VoiceStatus, WEBMCP_TOOL_PREFIX, WebMcpBridge, type WebMcpConfirmHandler, type WebMcpConfirmInfo, type WebMcpToolResult, type WidgetHostLayout, type WidgetHostLayoutMode, type WidgetLayoutSlot, type WidgetPreset, accessibilityPlugin, animationsPlugin, applyThemeVariables, attachHeaderToContainer, brandPlugin, buildComposer, buildDefaultHeader, buildHeader, buildHeaderWithLayout, buildMinimalHeader, builtInClientToolsForDispatch, collectEnrichedPageContext, componentRegistry, createActionManager, createAgentExperience, createAskUserQuestionBubble, createBestAvailableVoiceProvider, createBubbleWithLayout, createCSATFeedback, createComboButton, createComponentMiddleware, createComponentStreamParser, createDefaultSanitizer, createDemoCarousel, createDirectivePostprocessor, createDropdownMenu, createFlexibleJsonStreamParser, createIconButton, createImagePart, createJsonStreamParser, createLabelButton, createLocalStorageAdapter, createMarkdownProcessor, createMarkdownProcessorFromConfig, createMessageActions, createNPSFeedback, createPlainTextParser, createPlugin, createRegexJsonParser, createRovingTablist, createStandardBubble, createTextPart, createTheme, createThemeObserver, createToggleGroup, createTypingIndicator, createVoiceProvider, createWidgetHostLayout, createXmlParser, initAgentWidget as default, defaultActionHandlers, defaultJsonActionParser, defaultParseRules, detectColorScheme, directivePostprocessor, ensureAskUserQuestionSheet, escapeHtml, extractComponentDirectiveFromMessage, fileToImagePart, formatEnrichedContext, generateAssistantMessageId, generateCodeSnippet, generateMessageId, generateStableSelector, generateUserMessageId, getActiveTheme, getColorScheme, getDisplayText, getHeaderLayout, getImageParts, getPreset, hasComponentDirective, hasImages, headerLayouts, highContrastPlugin, initAgentWidget, isAskUserQuestionMessage, isComponentDirectiveType, isDockedMountMode, isSuggestRepliesMessage, isVoiceSupported, isWebMcpToolName, latestAgentSuggestions, listRegisteredStreamAnimations, loadMarkdownParsers, markdownPostprocessor, mergeWithDefaults, normalizeContent, onMarkdownParsersReady, parseAskUserQuestionPayload, parseSuggestRepliesPayload, pickBestVoice, pluginRegistry, reducedMotionPlugin, registerStreamAnimationPlugin, removeAskUserQuestionSheet, renderComponentDirective, renderLoadingIndicatorWithFallback, renderLucideIcon, resolveDockConfig, resolveSanitizer, resolveTokens, stripWebMcpPrefix, themeToCssVariables, unregisterStreamAnimationPlugin, validateImageFile, validateTheme };