@runtypelabs/persona 3.30.0 → 3.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2602
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-B_Qazlm4.d.cts → types-quh7NmYD.d.cts} +9 -0
- package/dist/animations/{types-B_Qazlm4.d.ts → types-quh7NmYD.d.ts} +9 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/codegen.cjs +4 -4
- package/dist/codegen.js +3 -3
- package/dist/index.cjs +46 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.global.js +77 -80
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +45 -45
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +2 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/smart-dom-reader.d.cts +50 -0
- package/dist/smart-dom-reader.d.ts +50 -0
- package/dist/theme-editor.cjs +39 -39
- package/dist/theme-editor.d.cts +50 -0
- package/dist/theme-editor.d.ts +50 -0
- package/dist/theme-editor.js +39 -39
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.js +1 -1
- package/dist/webmcp-polyfill.js +4 -0
- package/dist/widget.css +19 -0
- package/package.json +4 -3
- package/src/client.ts +6 -0
- package/src/components/approval-bubble.test.ts +52 -0
- package/src/components/approval-bubble.ts +20 -0
- package/src/components/panel.ts +7 -1
- package/src/defaults.ts +14 -0
- package/src/generated/runtype-openapi-contract.ts +4 -0
- package/src/index-global.ts +39 -0
- package/src/session.test.ts +62 -0
- package/src/session.ts +27 -0
- package/src/styles/widget.css +19 -0
- package/src/theme-reference.ts +1 -1
- package/src/types.ts +50 -0
- package/src/ui.scroll.test.ts +383 -0
- package/src/ui.ts +390 -40
- package/src/utils/auto-follow.test.ts +91 -0
- package/src/utils/auto-follow.ts +68 -0
- package/src/version.ts +5 -2
- package/src/webmcp-bridge.test.ts +60 -0
- package/src/webmcp-bridge.ts +34 -1
- package/src/webmcp-polyfill.ts +16 -0
package/dist/theme-reference.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var a in e)t(o,a,{get:e[a],enumerable:!0})},u=(o,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of d(e))!c.call(o,r)&&r!==a&&t(o,r,{get:()=>e[r],enumerable:!(s=l(e,r))||s.enumerable});return o};var g=o=>u(t({},"__esModule",{value:!0}),o);var h={};m(h,{THEME_EXAMPLES:()=>p,THEME_TOKEN_DOCS:()=>i,getThemeReference:()=>b});module.exports=g(h);var n={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var i={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text, shadow), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling, text templates, loading animations, and rendering hooks. Text templates support placeholders ({toolName}, {duration}) and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks, text templates, and loading animations. Text templates support {duration} placeholder and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"renderCollapsedSummary, renderCollapsedPreview, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped, expandable, loadingAnimation), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines, expandable, loadingAnimation), artifacts (sidebar config)."}}},p={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function b(){return{tokenDocs:i,defaultColorPalette:n.colors,defaultRadius:n.radius,examples:p,sdkPresets:["shop","minimal","fullscreen"]}}0&&(module.exports={THEME_EXAMPLES,THEME_TOKEN_DOCS,getThemeReference});
|
|
1
|
+
"use strict";var t=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var a in e)t(o,a,{get:e[a],enumerable:!0})},u=(o,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of d(e))!c.call(o,r)&&r!==a&&t(o,r,{get:()=>e[r],enumerable:!(s=l(e,r))||s.enumerable});return o};var g=o=>u(t({},"__esModule",{value:!0}),o);var h={};m(h,{THEME_EXAMPLES:()=>p,THEME_TOKEN_DOCS:()=>i,getThemeReference:()=>b});module.exports=g(h);var n={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var i={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text, shadow), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling, text templates, loading animations, and rendering hooks. Text templates support placeholders ({toolName}, {duration}) and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks, text templates, and loading animations. Text templates support {duration} placeholder and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"renderCollapsedSummary, renderCollapsedPreview, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, reasonColor, reasonLabel, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped, expandable, loadingAnimation), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines, expandable, loadingAnimation), artifacts (sidebar config)."}}},p={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function b(){return{tokenDocs:i,defaultColorPalette:n.colors,defaultRadius:n.radius,examples:p,sdkPresets:["shop","minimal","fullscreen"]}}0&&(module.exports={THEME_EXAMPLES,THEME_TOKEN_DOCS,getThemeReference});
|
package/dist/theme-reference.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var o={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text, shadow), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling, text templates, loading animations, and rendering hooks. Text templates support placeholders ({toolName}, {duration}) and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks, text templates, and loading animations. Text templates support {duration} placeholder and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"renderCollapsedSummary, renderCollapsedPreview, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped, expandable, loadingAnimation), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines, expandable, loadingAnimation), artifacts (sidebar config)."}}},r={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function m(){return{tokenDocs:o,defaultColorPalette:e.colors,defaultRadius:e.radius,examples:r,sdkPresets:["shop","minimal","fullscreen"]}}export{r as THEME_EXAMPLES,o as THEME_TOKEN_DOCS,m as getThemeReference};
|
|
1
|
+
var e={colors:{primary:{50:"#ffffff",100:"#f5f5f5",200:"#d4d4d4",300:"#a3a3a3",400:"#737373",500:"#171717",600:"#0f0f0f",700:"#0a0a0a",800:"#050505",900:"#030303",950:"#000000"},secondary:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},accent:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},success:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d"},warning:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12"},error:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d"},info:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"}},spacing:{0:"0px",1:"0.25rem",2:"0.5rem",3:"0.75rem",4:"1rem",5:"1.25rem",6:"1.5rem",8:"2rem",10:"2.5rem",12:"3rem",16:"4rem",20:"5rem",24:"6rem",32:"8rem",40:"10rem",48:"12rem",56:"14rem",64:"16rem"},typography:{fontFamily:{sans:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',serif:'Georgia, Cambria, "Times New Roman", Times, serif',mono:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},fontSize:{xs:"0.75rem",sm:"0.875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.625"}},shadows:{none:"none",sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)"},borders:{none:"none",sm:"1px solid",md:"2px solid",lg:"4px solid"},radius:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}};var o={overview:"Persona uses a three-layer design token system: palette \u2192 semantic \u2192 components. Most themes only need palette.colors overrides \u2014 semantic and component layers auto-derive from palette values. Config also accepts non-theme appearance options (launcher, sendButton, toolCall, etc.).",layers:{palette:{description:"Primitive design tokens. Override specific shades to change the entire widget feel.",colors:{description:"7 color scales, each with shades 50 (lightest) to 950 (darkest). Override only the shades you need.",scales:{gray:"Neutrals \u2014 backgrounds, text, borders. Key shades: 50 (lightest bg), 100 (secondary bg), 200 (borders), 500 (muted text), 900 (primary text).",primary:"Brand color \u2014 buttons, links, interactive elements. Key shades: 500 (default), 600 (hover).",accent:"Secondary highlight. Key shades: 500 (default), 600 (hover).",secondary:"Tertiary color scale.",success:"Positive feedback (default: green).",warning:"Caution feedback (default: yellow).",error:"Error/danger feedback (default: red)."}},radius:{description:"Border radius scale. Add custom keys like launcher, button.",defaults:{none:"0px",sm:"0.125rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem",full:"9999px"}},typography:{fontFamily:"Three stacks: sans (system-ui), serif (Georgia), mono (ui-monospace). Override individual stack values.",fontSize:"Scale: xs (0.75rem), sm (0.875rem), base (1rem), lg (1.125rem), xl (1.25rem), 2xl (1.5rem), 3xl (1.875rem), 4xl (2.25rem).",fontWeight:"normal (400), medium (500), semibold (600), bold (700).",lineHeight:"tight (1.25), normal (1.5), relaxed (1.625)."},shadows:"Scale: none, sm, md, lg, xl, 2xl. Values are CSS box-shadow strings.",borders:"Scale: none, sm (1px solid), md (2px solid), lg (4px solid).",spacing:"Scale: 0 (0px), 1 (0.25rem), 2 (0.5rem), 3 (0.75rem), 4 (1rem), 5 (1.25rem), 6 (1.5rem), 8 (2rem), 10 (2.5rem), 12 (3rem), 16-64."},semantic:{description:'Design intent tokens. Auto-derived from palette by default. Override to redirect token resolution. Values are token reference strings like "palette.colors.primary.500".',colors:{primary:"palette.colors.primary.500 \u2014 Primary brand color.",secondary:"palette.colors.gray.500 \u2014 Secondary color.",accent:"palette.colors.primary.600 \u2014 Accent/interactive color.",surface:"palette.colors.gray.50 \u2014 Panel/card backgrounds.",background:"palette.colors.gray.50 \u2014 Page background.",container:"palette.colors.gray.100 \u2014 Container backgrounds.",text:"palette.colors.gray.900 \u2014 Primary text.",textMuted:"palette.colors.gray.500 \u2014 Muted/secondary text.",textInverse:"palette.colors.gray.50 \u2014 Text on dark backgrounds.",border:"palette.colors.gray.200 \u2014 Default border color.",divider:"palette.colors.gray.200 \u2014 Divider lines.",interactive:{default:"palette.colors.primary.500",hover:"palette.colors.primary.600",focus:"palette.colors.primary.700",active:"palette.colors.primary.800",disabled:"palette.colors.gray.300"},feedback:{success:"palette.colors.success.500",warning:"palette.colors.warning.500",error:"palette.colors.error.500",info:"palette.colors.primary.500"}},spacing:"xs (0.25rem), sm (0.5rem), md (1rem), lg (1.5rem), xl (2rem), 2xl (2.5rem).",typography:"fontFamily, fontSize, fontWeight, lineHeight \u2014 reference palette typography tokens."},components:{description:"UI element tokens. Rarely needed for basic theming. Override for fine-grained control. All values are token references or raw CSS strings.",button:{description:"Three variants: primary, secondary, ghost.",properties:"background, foreground, borderRadius, padding."},input:{description:"Message input field.",properties:"background, placeholder, borderRadius, padding, focus.border, focus.ring."},launcher:{description:"Floating launcher button.",properties:"size (60px), iconSize (28px), borderRadius, shadow."},panel:{description:"Chat panel container.",properties:"width, maxWidth (440px), height (600px), maxHeight, borderRadius, shadow."},header:{description:"Chat panel header.",properties:"background, border, borderRadius, padding, iconBackground, iconForeground, titleForeground, subtitleForeground, actionIconForeground, shadow, borderBottom."},message:{description:"Chat message bubbles.",user:"background, text, borderRadius, shadow.",assistant:"background, text, borderRadius, border (optional), shadow (optional)."},markdown:{description:"Markdown rendering in messages and artifact pane.",properties:"inlineCode (background, foreground), link.foreground, prose.fontFamily, heading.h1/h2 (fontSize, fontWeight)."},voice:"recording (indicator, background, border), processing (icon, background), speaking (icon).",approval:"requested (background, border, text, shadow), approve (background, foreground), deny (background, foreground).",attachment:"image (background, border).",scrollToBottom:"Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.",toolBubble:"shadow \u2014 tool call row box-shadow.",reasoningBubble:"shadow \u2014 reasoning/thinking row box-shadow.",composer:"shadow \u2014 message input form box-shadow.",artifact:"toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground)."}},colorScheme:'"dark" merges darkTheme overrides on top of theme. "auto" detects system preference or <html class="dark">. "light" is default. colorScheme does NOT auto-invert colors \u2014 provide dark palette and semantic overrides yourself.',plugins:{description:"Plugins transform theme tokens before resolution. Use with createTheme().",available:{brandPlugin:'Auto-generates full color scales from a single brand hex: brandPlugin({ colors: { primary: "#7c3aed" } }).',accessibilityPlugin:"Enhanced focus indicators and disabled states.",highContrastPlugin:"Increased contrast for visual accessibility.",reducedMotionPlugin:"Disables all animations (sets transitions to 0ms).",animationsPlugin:"Adds transition and easing tokens."},usage:'createTheme(themeOverrides, { plugins: [brandPlugin({ colors: { primary: "#7c3aed" } })] })'},widgetConfig:{description:'Non-theme config options on the widget config object that affect appearance. These are siblings of "theme" in the config, not nested inside it.',launcher:{description:"Floating launcher button and panel positioning.",properties:{enabled:"Show/hide the launcher button.",title:"Header title text.",subtitle:"Header subtitle text.",position:'"bottom-right" | "bottom-left" | "top-right" | "top-left".',width:"Chat panel width (CSS value).",fullHeight:"Fill full height of container.",mountMode:'"floating" | "docked".',agentIconText:"Emoji/text for agent icon.",border:"Border style for launcher button.",shadow:"Box shadow for launcher button.",collapsedMaxWidth:"Max-width for launcher pill when panel closed."}},sendButton:{description:"Send button appearance.",properties:"backgroundColor, textColor, borderWidth, borderColor, paddingX, paddingY, iconText, iconName, size."},closeButton:{description:"Close button (on launcher config).",properties:"closeButtonSize, closeButtonColor, closeButtonBackgroundColor, closeButtonBorderWidth, closeButtonBorderColor, closeButtonBorderRadius."},clearChat:{description:"Clear chat button (on launcher.clearChat config).",properties:"enabled, iconColor, backgroundColor, borderWidth, borderColor, borderRadius, size."},scrollToBottom:{description:"Shared transcript + event-stream jump-to-latest affordance.",properties:'features.scrollToBottom.enabled, features.scrollToBottom.iconName, features.scrollToBottom.label (empty string renders icon-only). Defaults: enabled=true, iconName="arrow-down", label="".'},toolCall:{description:"Tool call display styling, text templates, loading animations, and rendering hooks. Text templates support placeholders ({toolName}, {duration}) and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"shadow, backgroundColor, borderColor, borderWidth, borderRadius, headerBackgroundColor, headerTextColor, headerPaddingX, headerPaddingY, contentBackgroundColor, contentTextColor, contentPaddingX, contentPaddingY, codeBlockBackgroundColor, codeBlockBorderColor, codeBlockTextColor, toggleTextColor, labelTextColor, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration, renderCollapsedSummary, renderCollapsedPreview, renderGroupedSummary."},reasoning:{description:"Reasoning/thinking row rendering hooks, text templates, and loading animations. Text templates support {duration} placeholder and inline formatting (~dim~, *italic*, **bold**). renderCollapsedSummary receives elapsed (static string) and createElapsedElement() (live-updating span) in its context.",properties:"renderCollapsedSummary, renderCollapsedPreview, activeTextTemplate, completeTextTemplate, loadingAnimationColor, loadingAnimationSecondaryColor, loadingAnimationDuration."},approval:{description:"Tool approval bubble styling and behavior. Set to false to disable.",properties:"backgroundColor, borderColor, titleColor, descriptionColor, reasonColor, reasonLabel, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, title, approveLabel, denyLabel."},copy:{description:"Widget text content.",properties:"showWelcomeCard (boolean), welcomeTitle, welcomeSubtitle, inputPlaceholder, sendButtonLabel."},voiceRecognition:{description:"Voice input configuration.",properties:"enabled, pauseDuration, iconColor, backgroundColor."},textToSpeech:{description:"Text-to-speech for assistant messages.",properties:'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.'},suggestionChips:"string[] \u2014 Suggested prompts shown to the user.",messageActions:{description:"Message action buttons (copy, upvote, downvote).",properties:'enabled, showCopy, showUpvote, showDownvote, visibility ("hover" | "always"), align ("left" | "center" | "right"), layout ("pill-inside" | "row-inside").'},attachments:{description:"File attachment configuration.",properties:"enabled, allowedTypes (string[]), maxFileSize (bytes), maxFiles, buttonIconName, buttonTooltipText."},markdown:{description:"Markdown rendering configuration.",properties:"options (gfm, breaks, headerIds, headerPrefix, pedantic, mangle, silent), disableDefaultStyles."},layout:{description:"Layout configuration.",showHeader:"boolean \u2014 show/hide the header section entirely.",showFooter:"boolean \u2014 show/hide the footer/composer section entirely.",contentMaxWidth:'CSS width value for centering content (e.g. "720px", "90ch").',header:'"default" | "minimal". Options: showIcon, showTitle, showSubtitle, showCloseButton, showClearChat.',messages:'"bubble" | "flat" | "minimal". Options: groupConsecutive, avatar (show, position, userAvatar, assistantAvatar), timestamp (show, position).'},statusIndicator:{description:"Status text shown below the composer.",properties:{visible:"Show/hide the status indicator.",align:'"left" | "center" | "right" \u2014 text alignment (default: "right").',idleText:'Text shown when idle (default: "Online").',idleLink:"URL to open when idle text is clicked (wraps text in a link).",connectingText:'Text shown while connecting (default: "Connecting\u2026").',connectedText:'Text shown while streaming (default: "Streaming\u2026").',errorText:'Text shown on error (default: "Offline").'}},features:{description:"Feature flags.",properties:"showReasoning (AI thinking steps), showToolCalls (tool invocations), toolCallDisplay (collapsedMode, activePreview, activeMinHeight, previewMaxLines, grouped, expandable, loadingAnimation), reasoningDisplay (activePreview, activeMinHeight, previewMaxLines, expandable, loadingAnimation), artifacts (sidebar config)."}}},r={darkIndigo:{description:"Dark mode with indigo accent \u2014 override grays for dark backgrounds and semantic tokens for inverted text/surface",theme:{palette:{colors:{primary:{500:"#6366f1",600:"#4f46e5"},gray:{50:"#f1f5f9",100:"#1e293b",200:"#334155",500:"#94a3b8",900:"#0f172a",950:"#020617"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.900",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",textInverse:"palette.colors.gray.900",border:"palette.colors.gray.200"}}}},warmVintage:{description:"Warm sepia tones with serif font and subtle radius",theme:{palette:{colors:{primary:{500:"#b45309",600:"#92400e"},gray:{50:"#fef3c7",100:"#fef9c3",200:"#d6d3d1",500:"#78716c",900:"#44403c"}},radius:{sm:"0.125rem",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:'Georgia, Cambria, "Times New Roman", Times, serif'}}}}},neonCyberpunk:{description:"Neon on dark with monospace font \u2014 full semantic override for dark background",theme:{palette:{colors:{primary:{500:"#f0abfc",600:"#e879f9"},accent:{500:"#22d3ee",600:"#06b6d4"},gray:{50:"#f0abfc",100:"#1e0a3c",200:"#3b0764",500:"#c084fc",900:"#0c0a1a",950:"#050412"}},radius:{sm:"0",md:"0.25rem",lg:"0.375rem"},typography:{fontFamily:{sans:"ui-monospace, SFMono-Regular, Menlo, monospace"}}},semantic:{colors:{surface:"palette.colors.gray.900",background:"palette.colors.gray.950",container:"palette.colors.gray.100",text:"palette.colors.gray.50",textMuted:"palette.colors.gray.500",border:"palette.colors.gray.200"}}}},cleanRounded:{description:"Clean light theme with large radius and panel styling",theme:{palette:{radius:{sm:"6px",md:"8px",lg:"12px",launcher:"50px",button:"8px"}},components:{panel:{borderRadius:"16px",shadow:"palette.shadows.2xl"}}}}};function m(){return{tokenDocs:o,defaultColorPalette:e.colors,defaultRadius:e.radius,examples:r,sdkPresets:["shop","minimal","fullscreen"]}}export{r as THEME_EXAMPLES,o as THEME_TOKEN_DOCS,m as getThemeReference};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var He=Object.defineProperty;var Fe=(e,t,r)=>t in e?He(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var _=(e,t,r)=>Fe(e,typeof t!="symbol"?t+"":t,r);function A(e,t){let r=typeof e;if(r!==typeof t)return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let n=e.length;if(n!==t.length)return!1;for(let i=0;i<n;i++)if(!A(e[i],t[i]))return!1;return!0}if(r==="object"){if(!e||!t)return e===t;let n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!1;for(let o of n)if(!A(e[o],t[o]))return!1;return!0}return e===t}function S(e){return encodeURI(Be(e))}function Be(e){return e.replace(/~/g,"~0").replace(/\//g,"~1")}var Ke={prefixItems:!0,items:!0,allOf:!0,anyOf:!0,oneOf:!0},Ge={$defs:!0,definitions:!0,properties:!0,patternProperties:!0,dependentSchemas:!0},Ye={id:!0,$id:!0,$ref:!0,$schema:!0,$anchor:!0,$vocabulary:!0,$comment:!0,default:!0,enum:!0,const:!0,required:!0,type:!0,maximum:!0,minimum:!0,exclusiveMaximum:!0,exclusiveMinimum:!0,multipleOf:!0,maxLength:!0,minLength:!0,pattern:!0,format:!0,maxItems:!0,minItems:!0,uniqueItems:!0,maxProperties:!0,minProperties:!0},Ze=typeof self!="undefined"&&self.location&&self.location.origin!=="null"?new URL(self.location.origin+self.location.pathname+location.search):new URL("https://github.com/cfworker");function E(e,t=Object.create(null),r=Ze,n=""){if(e&&typeof e=="object"&&!Array.isArray(e)){let d=e.$id||e.id;if(d){let o=new URL(d,r.href);o.hash.length>1?t[o.href]=e:(o.hash="",n===""?r=o:E(e,t,r))}}else if(e!==!0&&e!==!1)return t;let i=r.href+(n?"#"+n:"");if(t[i]!==void 0)throw new Error(`Duplicate schema URI "${i}".`);if(t[i]=e,e===!0||e===!1)return t;if(e.__absolute_uri__===void 0&&Object.defineProperty(e,"__absolute_uri__",{enumerable:!1,value:i}),e.$ref&&e.__absolute_ref__===void 0){let d=new URL(e.$ref,r.href);d.hash=d.hash,Object.defineProperty(e,"__absolute_ref__",{enumerable:!1,value:d.href})}if(e.$recursiveRef&&e.__absolute_recursive_ref__===void 0){let d=new URL(e.$recursiveRef,r.href);d.hash=d.hash,Object.defineProperty(e,"__absolute_recursive_ref__",{enumerable:!1,value:d.href})}if(e.$anchor){let d=new URL("#"+e.$anchor,r.href);t[d.href]=e}for(let d in e){if(Ye[d])continue;let o=`${n}/${S(d)}`,s=e[d];if(Array.isArray(s)){if(Ke[d]){let h=s.length;for(let x=0;x<h;x++)E(s[x],t,r,`${o}/${x}`)}}else if(Ge[d])for(let h in s)E(s[h],t,r,`${o}/${S(h)}`);else E(s,t,r,o)}return t}var Xe=/^(\d\d\d\d)-(\d\d)-(\d\d)$/,Qe=[0,31,28,31,30,31,30,31,31,30,31,30,31],Le=/^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i,et=/^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i,tt=/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,rt=/^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,nt=/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,ot=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,it=/^(?:\/(?:[^~/]|~0|~1)*)*$/,st=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,dt=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,at=e=>{if(e[0]==='"')return!1;let[t,r,...n]=e.split("@");return!t||!r||n.length!==0||t.length>64||r.length>253||t[0]==="."||t.endsWith(".")||t.includes("..")||!/^[a-z0-9.-]+$/i.test(r)||!/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/i.test(t)?!1:r.split(".").every(i=>/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i.test(i))},ft=/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,lt=/^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,ut=e=>e.length>1&&e.length<80&&(/^P\d+([.,]\d+)?W$/.test(e)||/^P[\dYMDTHS]*(\d[.,]\d+)?[YMDHS]$/.test(e)&&/^P([.,\d]+Y)?([.,\d]+M)?([.,\d]+D)?(T([.,\d]+H)?([.,\d]+M)?([.,\d]+S)?)?$/.test(e));function k(e){return e.test.bind(e)}var me={date:Ee,time:Me.bind(void 0,!1),"date-time":pt,duration:ut,uri:$t,"uri-reference":k(tt),"uri-template":k(rt),url:k(nt),email:at,hostname:k(et),ipv4:k(ft),ipv6:k(lt),regex:wt,uuid:k(ot),"json-pointer":k(it),"json-pointer-uri-fragment":k(st),"relative-json-pointer":k(dt)};function mt(e){return e%4===0&&(e%100!==0||e%400===0)}function Ee(e){let t=e.match(Xe);if(!t)return!1;let r=+t[1],n=+t[2],i=+t[3];return n>=1&&n<=12&&i>=1&&i<=(n==2&&mt(r)?29:Qe[n])}function Me(e,t){let r=t.match(Le);if(!r)return!1;let n=+r[1],i=+r[2],d=+r[3],o=!!r[5];return(n<=23&&i<=59&&d<=59||n==23&&i==59&&d==60)&&(!e||o)}var ct=/t|\s/i;function pt(e){let t=e.split(ct);return t.length==2&&Ee(t[0])&&Me(!0,t[1])}var yt=/\/|:/,ht=/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;function $t(e){return yt.test(e)&&ht.test(e)}var gt=/[^\\]\\Z/;function wt(e){if(gt.test(e))return!1;try{return new RegExp(e,"u"),!0}catch{return!1}}var Ce;(function(e){e[e.Flag=1]="Flag",e[e.Basic=2]="Basic",e[e.Detailed=4]="Detailed"})(Ce||(Ce={}));function Ne(e){let t=0,r=e.length,n=0,i;for(;n<r;)t++,i=e.charCodeAt(n++),i>=55296&&i<=56319&&n<r&&(i=e.charCodeAt(n),(i&64512)==56320&&n++);return t}function w(e,t,r="2019-09",n=E(t),i=!0,d=null,o="#",s="#",h=Object.create(null)){if(t===!0)return{valid:!0,errors:[]};if(t===!1)return{valid:!1,errors:[{instanceLocation:o,keyword:"false",keywordLocation:o,error:"False boolean schema."}]};let x=typeof e,$;switch(x){case"boolean":case"number":case"string":$=x;break;case"object":e===null?$="null":Array.isArray(e)?$="array":$="object";break;default:throw new Error(`Instances of "${x}" type are not supported.`)}let{$ref:T,$recursiveRef:q,$recursiveAnchor:M,type:I,const:z,enum:D,required:ye,not:he,anyOf:ee,allOf:te,oneOf:$e,if:ge,then:we,else:xe,format:U,properties:re,patternProperties:ne,additionalProperties:be,unevaluatedProperties:ve,minProperties:oe,maxProperties:ie,propertyNames:Se,dependentRequired:se,dependentSchemas:de,dependencies:ae,prefixItems:fe,items:R,additionalItems:Te,unevaluatedItems:_e,contains:Ie,minContains:O,maxContains:V,minItems:le,maxItems:ue,uniqueItems:Ue,minimum:C,maximum:N,exclusiveMinimum:J,exclusiveMaximum:W,multipleOf:H,minLength:F,maxLength:B,pattern:ke,__absolute_ref__:K,__absolute_recursive_ref__:Ve}=t,f=[];if(M===!0&&d===null&&(d=t),q==="#"){let m=d===null?n[Ve]:d,u=`${s}/$recursiveRef`,y=w(e,d===null?t:d,r,n,i,m,o,u,h);y.valid||f.push({instanceLocation:o,keyword:"$recursiveRef",keywordLocation:u,error:"A subschema had errors."},...y.errors)}if(T!==void 0){let u=n[K||T];if(u===void 0){let a=`Unresolved $ref "${T}".`;throw K&&K!==T&&(a+=` Absolute URI "${K}".`),a+=`
|
|
2
|
+
Known schemas:
|
|
3
|
+
- ${Object.keys(n).join(`
|
|
4
|
+
- `)}`,new Error(a)}let y=`${s}/$ref`,l=w(e,u,r,n,i,d,o,y,h);if(l.valid||f.push({instanceLocation:o,keyword:"$ref",keywordLocation:y,error:"A subschema had errors."},...l.errors),r==="4"||r==="7")return{valid:f.length===0,errors:f}}if(Array.isArray(I)){let m=I.length,u=!1;for(let y=0;y<m;y++)if($===I[y]||I[y]==="integer"&&$==="number"&&e%1===0&&e===e){u=!0;break}u||f.push({instanceLocation:o,keyword:"type",keywordLocation:`${s}/type`,error:`Instance type "${$}" is invalid. Expected "${I.join('", "')}".`})}else I==="integer"?($!=="number"||e%1||e!==e)&&f.push({instanceLocation:o,keyword:"type",keywordLocation:`${s}/type`,error:`Instance type "${$}" is invalid. Expected "${I}".`}):I!==void 0&&$!==I&&f.push({instanceLocation:o,keyword:"type",keywordLocation:`${s}/type`,error:`Instance type "${$}" is invalid. Expected "${I}".`});if(z!==void 0&&($==="object"||$==="array"?A(e,z)||f.push({instanceLocation:o,keyword:"const",keywordLocation:`${s}/const`,error:`Instance does not match ${JSON.stringify(z)}.`}):e!==z&&f.push({instanceLocation:o,keyword:"const",keywordLocation:`${s}/const`,error:`Instance does not match ${JSON.stringify(z)}.`})),D!==void 0&&($==="object"||$==="array"?D.some(m=>A(e,m))||f.push({instanceLocation:o,keyword:"enum",keywordLocation:`${s}/enum`,error:`Instance does not match any of ${JSON.stringify(D)}.`}):D.some(m=>e===m)||f.push({instanceLocation:o,keyword:"enum",keywordLocation:`${s}/enum`,error:`Instance does not match any of ${JSON.stringify(D)}.`})),he!==void 0){let m=`${s}/not`;w(e,he,r,n,i,d,o,m).valid&&f.push({instanceLocation:o,keyword:"not",keywordLocation:m,error:'Instance matched "not" schema.'})}let G=[];if(ee!==void 0){let m=`${s}/anyOf`,u=f.length,y=!1;for(let l=0;l<ee.length;l++){let a=ee[l],p=Object.create(h),c=w(e,a,r,n,i,M===!0?d:null,o,`${m}/${l}`,p);f.push(...c.errors),y=y||c.valid,c.valid&&G.push(p)}y?f.length=u:f.splice(u,0,{instanceLocation:o,keyword:"anyOf",keywordLocation:m,error:"Instance does not match any subschemas."})}if(te!==void 0){let m=`${s}/allOf`,u=f.length,y=!0;for(let l=0;l<te.length;l++){let a=te[l],p=Object.create(h),c=w(e,a,r,n,i,M===!0?d:null,o,`${m}/${l}`,p);f.push(...c.errors),y=y&&c.valid,c.valid&&G.push(p)}y?f.length=u:f.splice(u,0,{instanceLocation:o,keyword:"allOf",keywordLocation:m,error:"Instance does not match every subschema."})}if($e!==void 0){let m=`${s}/oneOf`,u=f.length,y=$e.filter((l,a)=>{let p=Object.create(h),c=w(e,l,r,n,i,M===!0?d:null,o,`${m}/${a}`,p);return f.push(...c.errors),c.valid&&G.push(p),c.valid}).length;y===1?f.length=u:f.splice(u,0,{instanceLocation:o,keyword:"oneOf",keywordLocation:m,error:`Instance does not match exactly one subschema (${y} matches).`})}if(($==="object"||$==="array")&&Object.assign(h,...G),ge!==void 0){let m=`${s}/if`;if(w(e,ge,r,n,i,d,o,m,h).valid){if(we!==void 0){let y=w(e,we,r,n,i,d,o,`${s}/then`,h);y.valid||f.push({instanceLocation:o,keyword:"if",keywordLocation:m,error:'Instance does not match "then" schema.'},...y.errors)}}else if(xe!==void 0){let y=w(e,xe,r,n,i,d,o,`${s}/else`,h);y.valid||f.push({instanceLocation:o,keyword:"if",keywordLocation:m,error:'Instance does not match "else" schema.'},...y.errors)}}if($==="object"){if(ye!==void 0)for(let l of ye)l in e||f.push({instanceLocation:o,keyword:"required",keywordLocation:`${s}/required`,error:`Instance does not have required property "${l}".`});let m=Object.keys(e);if(oe!==void 0&&m.length<oe&&f.push({instanceLocation:o,keyword:"minProperties",keywordLocation:`${s}/minProperties`,error:`Instance does not have at least ${oe} properties.`}),ie!==void 0&&m.length>ie&&f.push({instanceLocation:o,keyword:"maxProperties",keywordLocation:`${s}/maxProperties`,error:`Instance does not have at least ${ie} properties.`}),Se!==void 0){let l=`${s}/propertyNames`;for(let a in e){let p=`${o}/${S(a)}`,c=w(a,Se,r,n,i,d,p,l);c.valid||f.push({instanceLocation:o,keyword:"propertyNames",keywordLocation:l,error:`Property name "${a}" does not match schema.`},...c.errors)}}if(se!==void 0){let l=`${s}/dependantRequired`;for(let a in se)if(a in e){let p=se[a];for(let c of p)c in e||f.push({instanceLocation:o,keyword:"dependentRequired",keywordLocation:l,error:`Instance has "${a}" but does not have "${c}".`})}}if(de!==void 0)for(let l in de){let a=`${s}/dependentSchemas`;if(l in e){let p=w(e,de[l],r,n,i,d,o,`${a}/${S(l)}`,h);p.valid||f.push({instanceLocation:o,keyword:"dependentSchemas",keywordLocation:a,error:`Instance has "${l}" but does not match dependant schema.`},...p.errors)}}if(ae!==void 0){let l=`${s}/dependencies`;for(let a in ae)if(a in e){let p=ae[a];if(Array.isArray(p))for(let c of p)c in e||f.push({instanceLocation:o,keyword:"dependencies",keywordLocation:l,error:`Instance has "${a}" but does not have "${c}".`});else{let c=w(e,p,r,n,i,d,o,`${l}/${S(a)}`);c.valid||f.push({instanceLocation:o,keyword:"dependencies",keywordLocation:l,error:`Instance has "${a}" but does not match dependant schema.`},...c.errors)}}}let u=Object.create(null),y=!1;if(re!==void 0){let l=`${s}/properties`;for(let a in re){if(!(a in e))continue;let p=`${o}/${S(a)}`,c=w(e[a],re[a],r,n,i,d,p,`${l}/${S(a)}`);if(c.valid)h[a]=u[a]=!0;else if(y=i,f.push({instanceLocation:o,keyword:"properties",keywordLocation:l,error:`Property "${a}" does not match schema.`},...c.errors),y)break}}if(!y&&ne!==void 0){let l=`${s}/patternProperties`;for(let a in ne){let p=new RegExp(a,"u"),c=ne[a];for(let v in e){if(!p.test(v))continue;let Pe=`${o}/${S(v)}`,Oe=w(e[v],c,r,n,i,d,Pe,`${l}/${S(a)}`);Oe.valid?h[v]=u[v]=!0:(y=i,f.push({instanceLocation:o,keyword:"patternProperties",keywordLocation:l,error:`Property "${v}" matches pattern "${a}" but does not match associated schema.`},...Oe.errors))}}}if(!y&&be!==void 0){let l=`${s}/additionalProperties`;for(let a in e){if(u[a])continue;let p=`${o}/${S(a)}`,c=w(e[a],be,r,n,i,d,p,l);c.valid?h[a]=!0:(y=i,f.push({instanceLocation:o,keyword:"additionalProperties",keywordLocation:l,error:`Property "${a}" does not match additional properties schema.`},...c.errors))}}else if(!y&&ve!==void 0){let l=`${s}/unevaluatedProperties`;for(let a in e)if(!h[a]){let p=`${o}/${S(a)}`,c=w(e[a],ve,r,n,i,d,p,l);c.valid?h[a]=!0:f.push({instanceLocation:o,keyword:"unevaluatedProperties",keywordLocation:l,error:`Property "${a}" does not match unevaluated properties schema.`},...c.errors)}}}else if($==="array"){ue!==void 0&&e.length>ue&&f.push({instanceLocation:o,keyword:"maxItems",keywordLocation:`${s}/maxItems`,error:`Array has too many items (${e.length} > ${ue}).`}),le!==void 0&&e.length<le&&f.push({instanceLocation:o,keyword:"minItems",keywordLocation:`${s}/minItems`,error:`Array has too few items (${e.length} < ${le}).`});let m=e.length,u=0,y=!1;if(fe!==void 0){let l=`${s}/prefixItems`,a=Math.min(fe.length,m);for(;u<a;u++){let p=w(e[u],fe[u],r,n,i,d,`${o}/${u}`,`${l}/${u}`);if(h[u]=!0,!p.valid&&(y=i,f.push({instanceLocation:o,keyword:"prefixItems",keywordLocation:l,error:"Items did not match schema."},...p.errors),y))break}}if(R!==void 0){let l=`${s}/items`;if(Array.isArray(R)){let a=Math.min(R.length,m);for(;u<a;u++){let p=w(e[u],R[u],r,n,i,d,`${o}/${u}`,`${l}/${u}`);if(h[u]=!0,!p.valid&&(y=i,f.push({instanceLocation:o,keyword:"items",keywordLocation:l,error:"Items did not match schema."},...p.errors),y))break}}else for(;u<m;u++){let a=w(e[u],R,r,n,i,d,`${o}/${u}`,l);if(h[u]=!0,!a.valid&&(y=i,f.push({instanceLocation:o,keyword:"items",keywordLocation:l,error:"Items did not match schema."},...a.errors),y))break}if(!y&&Te!==void 0){let a=`${s}/additionalItems`;for(;u<m;u++){let p=w(e[u],Te,r,n,i,d,`${o}/${u}`,a);h[u]=!0,p.valid||(y=i,f.push({instanceLocation:o,keyword:"additionalItems",keywordLocation:a,error:"Items did not match additional items schema."},...p.errors))}}}if(Ie!==void 0)if(m===0&&O===void 0)f.push({instanceLocation:o,keyword:"contains",keywordLocation:`${s}/contains`,error:"Array is empty. It must contain at least one item matching the schema."});else if(O!==void 0&&m<O)f.push({instanceLocation:o,keyword:"minContains",keywordLocation:`${s}/minContains`,error:`Array has less items (${m}) than minContains (${O}).`});else{let l=`${s}/contains`,a=f.length,p=0;for(let c=0;c<m;c++){let v=w(e[c],Ie,r,n,i,d,`${o}/${c}`,l);v.valid?(h[c]=!0,p++):f.push(...v.errors)}p>=(O||0)&&(f.length=a),O===void 0&&V===void 0&&p===0?f.splice(a,0,{instanceLocation:o,keyword:"contains",keywordLocation:l,error:"Array does not contain item matching schema."}):O!==void 0&&p<O?f.push({instanceLocation:o,keyword:"minContains",keywordLocation:`${s}/minContains`,error:`Array must contain at least ${O} items matching schema. Only ${p} items were found.`}):V!==void 0&&p>V&&f.push({instanceLocation:o,keyword:"maxContains",keywordLocation:`${s}/maxContains`,error:`Array may contain at most ${V} items matching schema. ${p} items were found.`})}if(!y&&_e!==void 0){let l=`${s}/unevaluatedItems`;for(u;u<m;u++){if(h[u])continue;let a=w(e[u],_e,r,n,i,d,`${o}/${u}`,l);h[u]=!0,a.valid||f.push({instanceLocation:o,keyword:"unevaluatedItems",keywordLocation:l,error:"Items did not match unevaluated items schema."},...a.errors)}}if(Ue)for(let l=0;l<m;l++){let a=e[l],p=typeof a=="object"&&a!==null;for(let c=0;c<m;c++){if(l===c)continue;let v=e[c];(a===v||p&&(typeof v=="object"&&v!==null)&&A(a,v))&&(f.push({instanceLocation:o,keyword:"uniqueItems",keywordLocation:`${s}/uniqueItems`,error:`Duplicate items at indexes ${l} and ${c}.`}),l=Number.MAX_SAFE_INTEGER,c=Number.MAX_SAFE_INTEGER)}}}else if($==="number"){if(r==="4"?(C!==void 0&&(J===!0&&e<=C||e<C)&&f.push({instanceLocation:o,keyword:"minimum",keywordLocation:`${s}/minimum`,error:`${e} is less than ${J?"or equal to ":""} ${C}.`}),N!==void 0&&(W===!0&&e>=N||e>N)&&f.push({instanceLocation:o,keyword:"maximum",keywordLocation:`${s}/maximum`,error:`${e} is greater than ${W?"or equal to ":""} ${N}.`})):(C!==void 0&&e<C&&f.push({instanceLocation:o,keyword:"minimum",keywordLocation:`${s}/minimum`,error:`${e} is less than ${C}.`}),N!==void 0&&e>N&&f.push({instanceLocation:o,keyword:"maximum",keywordLocation:`${s}/maximum`,error:`${e} is greater than ${N}.`}),J!==void 0&&e<=J&&f.push({instanceLocation:o,keyword:"exclusiveMinimum",keywordLocation:`${s}/exclusiveMinimum`,error:`${e} is less than ${J}.`}),W!==void 0&&e>=W&&f.push({instanceLocation:o,keyword:"exclusiveMaximum",keywordLocation:`${s}/exclusiveMaximum`,error:`${e} is greater than or equal to ${W}.`})),H!==void 0){let m=e%H;Math.abs(0-m)>=11920929e-14&&Math.abs(H-m)>=11920929e-14&&f.push({instanceLocation:o,keyword:"multipleOf",keywordLocation:`${s}/multipleOf`,error:`${e} is not a multiple of ${H}.`})}}else if($==="string"){let m=F===void 0&&B===void 0?0:Ne(e);F!==void 0&&m<F&&f.push({instanceLocation:o,keyword:"minLength",keywordLocation:`${s}/minLength`,error:`String is too short (${m} < ${F}).`}),B!==void 0&&m>B&&f.push({instanceLocation:o,keyword:"maxLength",keywordLocation:`${s}/maxLength`,error:`String is too long (${m} > ${B}).`}),ke!==void 0&&!new RegExp(ke,"u").test(e)&&f.push({instanceLocation:o,keyword:"pattern",keywordLocation:`${s}/pattern`,error:"String does not match pattern."}),U!==void 0&&me[U]&&!me[U](e)&&f.push({instanceLocation:o,keyword:"format",keywordLocation:`${s}/format`,error:`String does not match format "${U}".`})}return{valid:f.length===0,errors:f}}var Y=class{constructor(t,r="2019-09",n=!0){_(this,"schema");_(this,"draft");_(this,"shortCircuit");_(this,"lookup");this.schema=t,this.draft=r,this.shortCircuit=n,this.lookup=E(t)}validate(t){return w(t,this.schema,this.draft,this.lookup,this.shortCircuit)}addSchema(t,r){r&&(t={...t,$id:r}),E(t,this.lookup)}};var Ae="Failed to parse input arguments",Q="Tool was executed but the invocation failed. For example, the script function threw an error",ce="Tool was cancelled",Z={type:"object",properties:{}},xt=["draft-2020-12","draft-07"],bt="__isWebMCPPolyfill",ze=Symbol("standardValidator"),g={installed:!1,previousNavigatorModelContextDescriptor:void 0,previousNavigatorModelContextTestingDescriptor:void 0,previousDocumentModelContextDescriptor:void 0,installedNavigatorModelContext:!1,installedNavigatorModelContextTesting:!1,installedDocumentModelContext:!1},vt=class extends EventTarget{constructor(){super(...arguments);_(this,"tools",new Map);_(this,"testingShim",null);_(this,"_ontoolchange",null);_(this,"unregisterToolDeprecationWarned",!1)}get ontoolchange(){return this._ontoolchange}set ontoolchange(t){this._ontoolchange=t}registerTool(t,r){var d;let n=r==null?void 0:r.signal;if(n!=null&&n.aborted){console.warn(`[WebMCPPolyfill] registerTool("${(d=t==null?void 0:t.name)!=null?d:"<unknown>"}") skipped: options.signal was already aborted.`);return}let i=Et(t,this.tools);this.tools.set(i.name,i),this.notifyToolsChanged(),n&&n.addEventListener("abort",()=>{this.tools.delete(i.name)&&this.notifyToolsChanged()},{once:!0})}unregisterTool(t){this.warnUnregisterToolDeprecationOnce();let r=_t(t);this.tools.delete(r)&&this.notifyToolsChanged()}getTools(){return Promise.resolve(this.getRegisteredToolInfos())}executeTool(t,r,n){return this.executeToolByName(t.name,r,n,!1)}getTestingShim(){return this.testingShim||(this.testingShim=new St(this)),this.testingShim}getToolInfos(){return[...this.tools.values()].map(t=>{var n;let r;try{r=JSON.stringify((n=t.inputSchema)!=null?n:{type:"object"})}catch{r='{"type":"object"}'}return{name:t.name,description:t.description,inputSchema:r}})}getRegisteredToolInfos(){return this.getToolInfos().map(t=>{var n,i,d;let r=this.tools.get(t.name);return{...t,title:(n=r==null?void 0:r.title)!=null?n:"",origin:(d=(i=globalThis.location)==null?void 0:i.origin)!=null?d:"",window:globalThis.window}})}async executeToolForTesting(t,r,n){return this.executeToolByName(t,r,n,!0)}async executeToolByName(t,r,n,i){var $;if(($=n==null?void 0:n.signal)!=null&&$.aborted)throw P(ce);let d=this.tools.get(t);if(!d)throw P(`Tool not found: ${t}`);let o=Tt(r),s=await At(o,d);if(s)throw P(s);let h=!0,x={requestUserInteraction:async T=>{if(!h)throw new Error(`ModelContextClient for tool "${t}" is no longer active after execute() resolved`);if(typeof T!="function")throw new TypeError("requestUserInteraction(callback) requires a function callback");return T()}};try{let T=d.execute(o,x),q=await Ut(Promise.resolve(T),n==null?void 0:n.signal);if(i)return qt(Jt(q));let M=JSON.stringify(q);return M===void 0?null:M}catch(T){throw P(T instanceof Error?`${Q}: ${T.message}`:Q)}finally{h=!1}}notifyToolsChanged(){queueMicrotask(()=>{var r,n;let t=new Event("toolchange");try{(r=this._ontoolchange)==null||r.call(this,t)}catch(i){console.warn("[WebMCPPolyfill] navigator.modelContext.ontoolchange handler threw:",i)}this.dispatchEvent(t),(n=this.testingShim)==null||n.dispatchToolChange()})}warnUnregisterToolDeprecationOnce(){this.unregisterToolDeprecationWarned||(this.unregisterToolDeprecationWarned=!0,console.warn("[WebMCPPolyfill] navigator.modelContext.unregisterTool() is deprecated. The April 23, 2026 WebMCP draft removed it in favor of registerTool(tool, { signal }) \u2014 pass an AbortSignal and abort it to unregister."))}},St=class extends EventTarget{constructor(t){super();_(this,"context");_(this,"_ontoolchange",null);this.context=t}listTools(){return this.context.getToolInfos()}executeTool(t,r,n){return this.context.executeToolForTesting(t,r,n)}getCrossDocumentScriptToolResult(){return Promise.resolve("[]")}get ontoolchange(){return this._ontoolchange}set ontoolchange(t){this._ontoolchange=t}registerToolsChangedCallback(t){if(typeof t!="function")throw new TypeError("Failed to execute 'registerToolsChangedCallback' on 'ModelContextTesting': parameter 1 is not of type 'Function'.");this.addEventListener("toolchange",t)}dispatchToolChange(){var r;let t=new Event("toolchange");try{(r=this._ontoolchange)==null||r.call(this,t)}catch(n){console.warn("[WebMCPPolyfill] ontoolchange handler threw:",n)}this.dispatchEvent(t),this.dispatchEvent(new Event("toolschanged"))}};function P(e){try{return new DOMException(e,"UnknownError")}catch{let t=new Error(e);return t.name="UnknownError",t}}function Tt(e){let t;try{t=JSON.parse(e)}catch{throw P(Ae)}if(!t||typeof t!="object"||Array.isArray(t))throw P(Ae);return t}function _t(e){if(typeof e=="string")return e;if(b(e)&&typeof e.name=="string")return e.name;throw new TypeError("Failed to execute 'unregisterTool' on 'ModelContext': parameter 1 must be a string or an object with a string name.")}function b(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function De(e){if(!b(e))return null;let t=e["~standard"];return b(t)?t:null}function It(e){let t=De(e);return!!(t&&t.version===1&&typeof t.validate=="function")}function kt(e){let t=De(e);return!t||t.version!==1||!b(t.jsonSchema)?!1:typeof t.jsonSchema.input=="function"}function X(e){return{"~standard":{version:1,vendor:"@mcp-b/webmcp-polyfill-json-schema",validate(t){if(!b(t))return{issues:[{message:"expected object arguments"}]};let r=Mt(t,e);return r?{issues:[r]}:{value:t}}}}}function Pt(e){for(let t of xt)try{let r=e["~standard"].jsonSchema.input({target:t});return Re(r),r}catch(r){console.warn(`[WebMCPPolyfill] Standard JSON Schema conversion failed for target "${t}":`,r)}throw new Error("Failed to convert Standard JSON Schema inputSchema to a JSON Schema object")}function Ot(e){if(e===void 0){let r=Z;return{inputSchema:r,standardValidator:X(r)}}if(kt(e)){let r=Pt(e);return{inputSchema:r,standardValidator:X(r)}}if(It(e))return{inputSchema:Z,standardValidator:e};if(Re(e),Object.keys(e).length===0)return{inputSchema:Z,standardValidator:X(Z)};let t=e.type===void 0?{type:"object",...e}:e;return{inputSchema:t,standardValidator:X(t)}}function Re(e){if(!b(e))throw new Error("inputSchema must be a JSON Schema object");j(e,"$")}function j(e,t){let r=e.type;if(r!==void 0&&typeof r!="string"&&!(Array.isArray(r)&&r.every(s=>typeof s=="string"&&s.length>0)))throw new Error(`Invalid JSON Schema at ${t}: "type" must be a string or string[]`);let n=e.required;if(n!==void 0&&!(Array.isArray(n)&&n.every(s=>typeof s=="string")))throw new Error(`Invalid JSON Schema at ${t}: "required" must be an array of strings`);let i=e.properties;if(i!==void 0){if(!b(i))throw new Error(`Invalid JSON Schema at ${t}: "properties" must be an object`);for(let[s,h]of Object.entries(i)){if(!b(h))throw new Error(`Invalid JSON Schema at ${t}.properties.${s}: expected object schema`);j(h,`${t}.properties.${s}`)}}let d=e.items;if(d!==void 0)if(Array.isArray(d))for(let[s,h]of d.entries()){if(!b(h))throw new Error(`Invalid JSON Schema at ${t}.items[${s}]: expected object schema`);j(h,`${t}.items[${s}]`)}else if(b(d))j(d,`${t}.items`);else throw new Error(`Invalid JSON Schema at ${t}: "items" must be an object or object[]`);for(let s of["allOf","anyOf","oneOf"]){let h=e[s];if(h!==void 0){if(!Array.isArray(h))throw new Error(`Invalid JSON Schema at ${t}: "${s}" must be an array`);for(let[x,$]of h.entries()){if(!b($))throw new Error(`Invalid JSON Schema at ${t}.${s}[${x}]: expected object schema`);j($,`${t}.${s}[${x}]`)}}}let o=e.not;if(o!==void 0){if(!b(o))throw new Error(`Invalid JSON Schema at ${t}: "not" must be an object schema`);j(o,`${t}.not`)}try{JSON.stringify(e)}catch{throw new Error(`Invalid JSON Schema at ${t}: schema must be JSON-serializable`)}}function Et(e,t){if(!e||typeof e!="object")throw new TypeError("registerTool(tool) requires a tool object");if(typeof e.name!="string"||e.name.length===0)throw new TypeError('Tool "name" must be a non-empty string');if(typeof e.description!="string"||e.description.length===0)throw new TypeError('Tool "description" must be a non-empty string');if(typeof e.execute!="function")throw new TypeError('Tool "execute" must be a function');if(t.has(e.name))throw new Error(`Tool already registered: ${e.name}`);let r=Ot(e.inputSchema),n=e.annotations,i=n?{...n,...n.readOnlyHint==="true"?{readOnlyHint:!0}:n.readOnlyHint==="false"?{readOnlyHint:!1}:{},...n.destructiveHint==="true"?{destructiveHint:!0}:n.destructiveHint==="false"?{destructiveHint:!1}:{},...n.idempotentHint==="true"?{idempotentHint:!0}:n.idempotentHint==="false"?{idempotentHint:!1}:{},...n.openWorldHint==="true"?{openWorldHint:!0}:n.openWorldHint==="false"?{openWorldHint:!1}:{}}:void 0;return{...e,...i?{annotations:i}:{},inputSchema:r.inputSchema,[ze]:r.standardValidator}}function Mt(e,t){let r=new Y(t,"2020-12",!0).validate(e);if(r.valid)return null;let n=r.errors[r.errors.length-1];return n?{message:n.error}:{message:"Input validation failed"}}function Ct(e){if(!e||e.length===0)return null;let t=e.map(r=>b(r)&&"key"in r?r.key:r).map(r=>String(r)).filter(r=>r.length>0);return t.length===0?null:t.join(".")}async function Nt(e,t){let r;try{r=await Promise.resolve(t["~standard"].validate(e))}catch(d){let o=d instanceof Error?`: ${d.message}`:"";return console.error("[WebMCPPolyfill] Standard Schema validation threw unexpectedly:",d),`Input validation error: schema validation failed${o}`}if(!r.issues||r.issues.length===0)return null;let n=r.issues[0];if(!n)return"Input validation error";let i=Ct(n==null?void 0:n.path);return i?`Input validation error: ${n.message} at ${i}`:`Input validation error: ${n.message}`}async function At(e,t){return Nt(e,t[ze])}function jt(e){return b(e)&&Array.isArray(e.content)}function zt(e){return e===null||typeof e=="string"||typeof e=="number"||typeof e=="boolean"}function pe(e){return zt(e)?Number.isFinite(e)||typeof e!="number":Array.isArray(e)?e.every(t=>pe(t)):b(e)?Object.values(e).every(t=>pe(t)):!1}function Dt(e){if(!(!b(e)||!pe(e)))return e}function Rt(e){var t;if(typeof e=="string")return e;try{return(t=JSON.stringify(e))!=null?t:String(e)}catch{return String(e)}}function Jt(e){if(jt(e))return e;let t=Dt(e);return{content:[{type:"text",text:Rt(e)}],...t?{structuredContent:t}:{},isError:!1}}function Wt(e){var t;for(let r of(t=e.content)!=null?t:[])if(r.type==="text"&&"text"in r&&typeof r.text=="string")return r.text;return null}function qt(e){var r;if(e.isError)throw P(((r=Wt(e))==null?void 0:r.replace(/^Error:\s*/i,"").trim())||Q);let t=e.metadata;if(t&&typeof t=="object"&&t.willNavigate)return null;try{return JSON.stringify(e)}catch{throw P(Q)}}function Ut(e,t){return t?t.aborted?Promise.reject(P(ce)):new Promise((r,n)=>{let i=()=>{d(),n(P(ce))},d=()=>{t.removeEventListener("abort",i)};t.addEventListener("abort",i,{once:!0}),e.then(o=>{d(),r(o)},o=>{d(),n(o)})}):e}function Je(){return typeof navigator!="undefined"?navigator:null}function We(){return typeof document!="undefined"?document:null}function Vt(e,t,r){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,writable:!1,value:r})}function je(e,t){Object.defineProperty(e,"modelContext",{configurable:!0,enumerable:!0,writable:!1,value:t})}var L=!1;function Ht(e,t){Object.defineProperty(e,"modelContext",{configurable:!0,enumerable:!0,get(){return L||(L=!0,console.warn("[WebMCPPolyfill] navigator.modelContext is deprecated. The May 27, 2026 WebMCP draft moved the modelContext getter from Navigator to Document \u2014 use document.modelContext instead. See https://github.com/webmachinelearning/webmcp/pull/184.")),t}})}function qe(e){var h;let t=Je(),r=We();if(!t&&!r||(r==null?void 0:r.modelContext))return;let i=t==null?void 0:t.modelContext,d=!!i;if(g.installed&&Ft(),r&&i){g.previousDocumentModelContextDescriptor=Object.getOwnPropertyDescriptor(r,"modelContext"),je(r,i),g.installedDocumentModelContext=!0,g.installed=!0;return}if(d)return;let o=new vt,s=o;if(s[bt]=!0,r&&(g.previousDocumentModelContextDescriptor=Object.getOwnPropertyDescriptor(r,"modelContext"),je(r,s),g.installedDocumentModelContext=!0),t){g.previousNavigatorModelContextDescriptor=Object.getOwnPropertyDescriptor(t,"modelContext"),g.previousNavigatorModelContextTestingDescriptor=Object.getOwnPropertyDescriptor(t,"modelContextTesting"),L=!1,Ht(t,s),g.installedNavigatorModelContext=!0;let x=(h=e==null?void 0:e.installTestingShim)!=null?h:"if-missing",$=!!t.modelContextTesting;(x==="always"||(x===!0||x==="if-missing")&&!$)&&(Vt(t,"modelContextTesting",o.getTestingShim()),g.installedNavigatorModelContextTesting=!0)}g.installed=!0}function Ft(){if(!g.installed)return;let e=(n,i,d)=>{if(d){Object.defineProperty(n,i,d);return}delete n[i]},t=Je(),r=We();r&&g.installedDocumentModelContext&&e(r,"modelContext",g.previousDocumentModelContextDescriptor),t&&g.installedNavigatorModelContext&&e(t,"modelContext",g.previousNavigatorModelContextDescriptor),t&&g.installedNavigatorModelContextTesting&&e(t,"modelContextTesting",g.previousNavigatorModelContextTestingDescriptor),g.installed=!1,g.previousDocumentModelContextDescriptor=void 0,g.previousNavigatorModelContextDescriptor=void 0,g.previousNavigatorModelContextTestingDescriptor=void 0,g.installedDocumentModelContext=!1,g.installedNavigatorModelContext=!1,g.installedNavigatorModelContextTesting=!1,L=!1}if(typeof window!="undefined"&&typeof document!="undefined"){let e=window.__webMCPPolyfillOptions;if((e==null?void 0:e.autoInitialize)!==!1)try{qe(e)}catch(t){console.error("[WebMCPPolyfill] Auto-initialization failed:",t)}}export{qe as initializeWebMCPPolyfill};
|
package/dist/widget.css
CHANGED
|
@@ -2616,6 +2616,25 @@
|
|
|
2616
2616
|
height: var(--persona-scroll-to-bottom-icon-size, 14px);
|
|
2617
2617
|
}
|
|
2618
2618
|
|
|
2619
|
+
/* New-messages count badge pinned to the affordance's top-right corner. */
|
|
2620
|
+
[data-persona-root] .persona-scroll-to-bottom-indicator [data-persona-scroll-to-bottom-count] {
|
|
2621
|
+
position: absolute;
|
|
2622
|
+
top: -6px;
|
|
2623
|
+
right: -6px;
|
|
2624
|
+
box-sizing: border-box;
|
|
2625
|
+
min-width: 18px;
|
|
2626
|
+
height: 18px;
|
|
2627
|
+
padding: 0 5px;
|
|
2628
|
+
border-radius: var(--persona-radius-full, 9999px);
|
|
2629
|
+
border: 1px solid var(--persona-scroll-to-bottom-border, var(--persona-primary, #111827));
|
|
2630
|
+
background: var(--persona-scroll-to-bottom-count-bg, var(--persona-surface, #ffffff));
|
|
2631
|
+
color: var(--persona-scroll-to-bottom-count-fg, var(--persona-primary, #111827));
|
|
2632
|
+
font-size: 11px;
|
|
2633
|
+
font-weight: 600;
|
|
2634
|
+
line-height: 16px;
|
|
2635
|
+
text-align: center;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2619
2638
|
[data-persona-root] .persona-scroll-to-bottom-indicator:hover {
|
|
2620
2639
|
opacity: 0.92;
|
|
2621
2640
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/persona",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.31.1",
|
|
4
4
|
"description": "Themeable, pluggable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"access": "public"
|
|
110
110
|
},
|
|
111
111
|
"scripts": {
|
|
112
|
-
"build": "rimraf dist && pnpm run build:styles && pnpm run build:client && pnpm run build:installer && pnpm run build:launcher && pnpm run build:theme-ref && pnpm run build:codegen && pnpm run build:theme-editor && pnpm run build:testing && pnpm run build:smart-dom-reader && pnpm run build:plugin-kit && pnpm run build:animations",
|
|
112
|
+
"build": "rimraf dist && pnpm run build:styles && pnpm run build:client && pnpm run build:installer && pnpm run build:launcher && pnpm run build:webmcp-polyfill && pnpm run build:theme-ref && pnpm run build:codegen && pnpm run build:theme-editor && pnpm run build:testing && pnpm run build:smart-dom-reader && pnpm run build:plugin-kit && pnpm run build:animations",
|
|
113
113
|
"build:plugin-kit": "tsup src/plugin-kit.ts --format esm,cjs --minify --dts --out-dir dist --no-splitting",
|
|
114
114
|
"build:theme-editor": "tsup src/theme-editor.ts --format esm,cjs --minify --dts --out-dir dist --no-splitting",
|
|
115
115
|
"build:testing": "tsup src/testing.ts --format esm,cjs --minify --dts --out-dir dist --no-splitting",
|
|
@@ -118,7 +118,8 @@
|
|
|
118
118
|
"build:theme-ref": "tsup src/theme-reference.ts --format esm,cjs --minify --dts",
|
|
119
119
|
"build:codegen": "tsup src/codegen.ts --format esm,cjs --minify --dts",
|
|
120
120
|
"build:styles": "node -e \"const fs=require('fs');fs.mkdirSync('dist',{recursive:true});fs.copyFileSync('src/styles/widget.css','dist/widget.css');\"",
|
|
121
|
-
"build:client": "tsup src/index.ts --format esm,cjs --minify --sourcemap --splitting false --dts --loader \".css=text\" && tsup
|
|
121
|
+
"build:client": "tsup src/index.ts --format esm,cjs --minify --sourcemap --splitting false --dts --loader \".css=text\" && tsup --config tsup.global.config.ts && node -e \"const fs=require('fs');for(const ext of ['.global.js','.global.js.map']){const from='dist/index-global'+ext;if(fs.existsSync(from))fs.renameSync(from,'dist/index'+ext);}\"",
|
|
122
|
+
"build:webmcp-polyfill": "tsup --config tsup.webmcp-polyfill.config.ts",
|
|
122
123
|
"build:installer": "tsup src/install.ts --format iife --global-name SiteAgentInstaller --out-dir dist --minify --sourcemap --no-splitting",
|
|
123
124
|
"build:launcher": "tsup src/launcher-global.ts --format iife --global-name AgentWidgetLauncher --minify --sourcemap --splitting false --out-dir dist && node -e \"const fs=require('fs');for(const ext of ['.global.js','.global.js.map']){const from='dist/launcher-global'+ext;if(fs.existsSync(from))fs.renameSync(from,'dist/launcher'+ext);}\"",
|
|
124
125
|
"lint": "eslint . --ext .ts",
|
package/src/client.ts
CHANGED
|
@@ -3045,6 +3045,9 @@ export class AgentWidgetClient {
|
|
|
3045
3045
|
toolName: payload.toolName ?? '',
|
|
3046
3046
|
toolType: payload.toolType,
|
|
3047
3047
|
description: payload.description ?? `Execute ${payload.toolName ?? 'tool'}`,
|
|
3048
|
+
...(typeof payload.reason === "string" && payload.reason
|
|
3049
|
+
? { reason: payload.reason }
|
|
3050
|
+
: {}),
|
|
3048
3051
|
parameters: payload.parameters,
|
|
3049
3052
|
},
|
|
3050
3053
|
};
|
|
@@ -3067,6 +3070,9 @@ export class AgentWidgetClient {
|
|
|
3067
3070
|
toolName: payload.toolName ?? '',
|
|
3068
3071
|
toolType: payload.toolType,
|
|
3069
3072
|
description: payload.description ?? `Execute ${payload.toolName ?? 'tool'}`,
|
|
3073
|
+
...(typeof payload.reason === "string" && payload.reason
|
|
3074
|
+
? { reason: payload.reason }
|
|
3075
|
+
: {}),
|
|
3070
3076
|
parameters: payload.parameters,
|
|
3071
3077
|
},
|
|
3072
3078
|
};
|
|
@@ -266,3 +266,55 @@ describe("updateApprovalDetailsUI", () => {
|
|
|
266
266
|
expect(getToggle(bubble)?.textContent).toContain("Show details");
|
|
267
267
|
});
|
|
268
268
|
});
|
|
269
|
+
|
|
270
|
+
describe("createApprovalBubble agent reason", () => {
|
|
271
|
+
it("renders the attributed reason line as plain text when present", () => {
|
|
272
|
+
const bubble = createApprovalBubble(
|
|
273
|
+
makeDetailedMessage({
|
|
274
|
+
reason: "Adds the <b>large</b> blue tee to your cart as you asked.",
|
|
275
|
+
})
|
|
276
|
+
);
|
|
277
|
+
const reasonLine = bubble.querySelector("[data-approval-reason]") as HTMLElement;
|
|
278
|
+
expect(reasonLine).not.toBeNull();
|
|
279
|
+
expect(reasonLine.textContent).toContain("Agent's stated reason:");
|
|
280
|
+
expect(reasonLine.textContent).toContain(
|
|
281
|
+
"Adds the <b>large</b> blue tee to your cart as you asked."
|
|
282
|
+
);
|
|
283
|
+
// Plain text rendering — markup in the agent-authored string must not
|
|
284
|
+
// become elements (prompt-injection surface).
|
|
285
|
+
expect(reasonLine.querySelector("b")).toBeNull();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("omits the reason line when no reason is provided", () => {
|
|
289
|
+
const bubble = createApprovalBubble(makeDetailedMessage());
|
|
290
|
+
expect(bubble.querySelector("[data-approval-reason]")).toBeNull();
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it("applies reasonColor and a custom reasonLabel from config", () => {
|
|
294
|
+
const config: AgentWidgetConfig = {
|
|
295
|
+
approval: { reasonColor: "rgb(1, 2, 3)", reasonLabel: "Why:" },
|
|
296
|
+
} as AgentWidgetConfig;
|
|
297
|
+
const bubble = createApprovalBubble(
|
|
298
|
+
makeDetailedMessage({ reason: "Because you asked." }),
|
|
299
|
+
config
|
|
300
|
+
);
|
|
301
|
+
const reasonLine = bubble.querySelector("[data-approval-reason]") as HTMLElement;
|
|
302
|
+
expect(reasonLine.style.color).toBe("rgb(1, 2, 3)");
|
|
303
|
+
expect(reasonLine.textContent).toContain("Why:");
|
|
304
|
+
expect(reasonLine.textContent).not.toContain("Agent's stated reason:");
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("passes the reason to formatDescription", () => {
|
|
308
|
+
let seenReason: string | undefined;
|
|
309
|
+
const config: AgentWidgetConfig = {
|
|
310
|
+
approval: {
|
|
311
|
+
formatDescription: (approval: { reason?: string }) => {
|
|
312
|
+
seenReason = approval.reason;
|
|
313
|
+
return undefined;
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
} as AgentWidgetConfig;
|
|
317
|
+
createApprovalBubble(makeDetailedMessage({ reason: "Because." }), config);
|
|
318
|
+
expect(seenReason).toBe("Because.");
|
|
319
|
+
});
|
|
320
|
+
});
|
|
@@ -257,6 +257,7 @@ export const createApprovalBubble = (
|
|
|
257
257
|
description: approval.description,
|
|
258
258
|
parameters: approval.parameters,
|
|
259
259
|
...(declaredTitle ? { displayTitle: declaredTitle } : {}),
|
|
260
|
+
...(approval.reason ? { reason: approval.reason } : {}),
|
|
260
261
|
});
|
|
261
262
|
const summaryFallsBackToDescription = !approval.toolName;
|
|
262
263
|
const summaryText =
|
|
@@ -273,6 +274,25 @@ export const createApprovalBubble = (
|
|
|
273
274
|
summary.textContent = summaryText;
|
|
274
275
|
content.appendChild(summary);
|
|
275
276
|
|
|
277
|
+
// Agent-authored justification for this specific call. It is the agent's
|
|
278
|
+
// own claim about its intent (attacker-writable under prompt injection), so
|
|
279
|
+
// it is rendered as plain text via textContent — never markdown/HTML — and
|
|
280
|
+
// explicitly attributed to the agent rather than spoken in system voice.
|
|
281
|
+
if (approval.reason) {
|
|
282
|
+
const reasonLine = createElement("p", "persona-text-sm persona-mt-1 persona-text-persona-muted");
|
|
283
|
+
reasonLine.setAttribute("data-approval-reason", "true");
|
|
284
|
+
if (approvalConfig?.reasonColor) {
|
|
285
|
+
reasonLine.style.color = approvalConfig.reasonColor;
|
|
286
|
+
} else if (approvalConfig?.descriptionColor) {
|
|
287
|
+
reasonLine.style.color = approvalConfig.descriptionColor;
|
|
288
|
+
}
|
|
289
|
+
const reasonLabel = createElement("span", "persona-font-medium");
|
|
290
|
+
reasonLabel.textContent = `${approvalConfig?.reasonLabel ?? "Agent's stated reason:"} `;
|
|
291
|
+
reasonLine.appendChild(reasonLabel);
|
|
292
|
+
reasonLine.appendChild(document.createTextNode(approval.reason));
|
|
293
|
+
content.appendChild(reasonLine);
|
|
294
|
+
}
|
|
295
|
+
|
|
276
296
|
// Technical details: agent-facing description + raw parameters JSON,
|
|
277
297
|
// collapsed behind a toggle by default (`approval.detailsDisplay`).
|
|
278
298
|
const detailsMode = approvalConfig?.detailsDisplay ?? "collapsed";
|
package/src/components/panel.ts
CHANGED
|
@@ -262,6 +262,9 @@ const buildComposerBarPanel = (
|
|
|
262
262
|
body.style.paddingTop = "48px";
|
|
263
263
|
body.id = "persona-scroll-container";
|
|
264
264
|
body.setAttribute("data-persona-theme-zone", "messages");
|
|
265
|
+
// Reserve the scrollbar gutter so the transcript doesn't shift horizontally
|
|
266
|
+
// when streaming content first overflows and the scrollbar appears.
|
|
267
|
+
body.style.setProperty("scrollbar-gutter", "stable");
|
|
265
268
|
|
|
266
269
|
const introCard = createElement(
|
|
267
270
|
"div",
|
|
@@ -399,7 +402,10 @@ export const buildPanel = (config?: AgentWidgetConfig, showClose = true): PanelE
|
|
|
399
402
|
);
|
|
400
403
|
body.id = "persona-scroll-container";
|
|
401
404
|
body.setAttribute("data-persona-theme-zone", "messages");
|
|
402
|
-
|
|
405
|
+
// Reserve the scrollbar gutter so the transcript doesn't shift horizontally
|
|
406
|
+
// when streaming content first overflows and the scrollbar appears.
|
|
407
|
+
body.style.setProperty("scrollbar-gutter", "stable");
|
|
408
|
+
|
|
403
409
|
const introCard = createElement(
|
|
404
410
|
"div",
|
|
405
411
|
"persona-rounded-2xl persona-bg-persona-surface persona-p-6"
|
package/src/defaults.ts
CHANGED
|
@@ -123,6 +123,10 @@ export const DEFAULT_WIDGET_CONFIG: Partial<AgentWidgetConfig> = {
|
|
|
123
123
|
iconName: "arrow-down",
|
|
124
124
|
label: "",
|
|
125
125
|
},
|
|
126
|
+
scrollBehavior: {
|
|
127
|
+
mode: "follow",
|
|
128
|
+
anchorTopOffset: 16,
|
|
129
|
+
},
|
|
126
130
|
toolCallDisplay: {
|
|
127
131
|
collapsedMode: "tool-call",
|
|
128
132
|
activePreview: false,
|
|
@@ -264,6 +268,8 @@ export function mergeWithDefaults(
|
|
|
264
268
|
const ca = config.features?.artifacts;
|
|
265
269
|
const dsb = DEFAULT_WIDGET_CONFIG.features?.scrollToBottom;
|
|
266
270
|
const csb = config.features?.scrollToBottom;
|
|
271
|
+
const dsc = DEFAULT_WIDGET_CONFIG.features?.scrollBehavior;
|
|
272
|
+
const csc = config.features?.scrollBehavior;
|
|
267
273
|
const dsa = DEFAULT_WIDGET_CONFIG.features?.streamAnimation;
|
|
268
274
|
const csa = config.features?.streamAnimation;
|
|
269
275
|
const dau = DEFAULT_WIDGET_CONFIG.features?.askUserQuestion;
|
|
@@ -286,6 +292,13 @@ export function mergeWithDefaults(
|
|
|
286
292
|
...dsb,
|
|
287
293
|
...csb,
|
|
288
294
|
};
|
|
295
|
+
const mergedScrollBehavior =
|
|
296
|
+
dsc === undefined && csc === undefined
|
|
297
|
+
? undefined
|
|
298
|
+
: {
|
|
299
|
+
...dsc,
|
|
300
|
+
...csc,
|
|
301
|
+
};
|
|
289
302
|
const mergedStreamAnimation =
|
|
290
303
|
dsa === undefined && csa === undefined
|
|
291
304
|
? undefined
|
|
@@ -308,6 +321,7 @@ export function mergeWithDefaults(
|
|
|
308
321
|
...DEFAULT_WIDGET_CONFIG.features,
|
|
309
322
|
...config.features,
|
|
310
323
|
...(mergedScrollToBottom !== undefined ? { scrollToBottom: mergedScrollToBottom } : {}),
|
|
324
|
+
...(mergedScrollBehavior !== undefined ? { scrollBehavior: mergedScrollBehavior } : {}),
|
|
311
325
|
...(mergedArtifacts !== undefined ? { artifacts: mergedArtifacts } : {}),
|
|
312
326
|
...(mergedStreamAnimation !== undefined ? { streamAnimation: mergedStreamAnimation } : {}),
|
|
313
327
|
...(mergedAskUserQuestion !== undefined ? { askUserQuestion: mergedAskUserQuestion } : {}),
|
|
@@ -150,6 +150,7 @@ export type RuntypeAgentSSEEvent = {
|
|
|
150
150
|
};
|
|
151
151
|
iteration?: number;
|
|
152
152
|
parameters?: Record<string, unknown>;
|
|
153
|
+
reason?: string;
|
|
153
154
|
seq: number;
|
|
154
155
|
startedAt: string;
|
|
155
156
|
timeout: number;
|
|
@@ -422,6 +423,7 @@ export type RuntypeFlowSSEEvent = {
|
|
|
422
423
|
when: string;
|
|
423
424
|
} | {
|
|
424
425
|
executionId?: string;
|
|
426
|
+
reason?: string;
|
|
425
427
|
seq?: number;
|
|
426
428
|
type: "step_await";
|
|
427
429
|
[key: string]: unknown;
|
|
@@ -701,6 +703,7 @@ export type RuntypeDispatchSSEEvent = {
|
|
|
701
703
|
};
|
|
702
704
|
iteration?: number;
|
|
703
705
|
parameters?: Record<string, unknown>;
|
|
706
|
+
reason?: string;
|
|
704
707
|
seq: number;
|
|
705
708
|
startedAt: string;
|
|
706
709
|
timeout: number;
|
|
@@ -971,6 +974,7 @@ export type RuntypeDispatchSSEEvent = {
|
|
|
971
974
|
when: string;
|
|
972
975
|
} | {
|
|
973
976
|
executionId?: string;
|
|
977
|
+
reason?: string;
|
|
974
978
|
seq?: number;
|
|
975
979
|
type: "step_await";
|
|
976
980
|
[key: string]: unknown;
|
package/src/index-global.ts
CHANGED
|
@@ -31,3 +31,42 @@ export {
|
|
|
31
31
|
listRegisteredStreamAnimations,
|
|
32
32
|
} from "./utils/stream-animation";
|
|
33
33
|
export type { StreamAnimationPlugin, StreamAnimationContext } from "./types";
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Deferred WebMCP polyfill loading.
|
|
37
|
+
//
|
|
38
|
+
// This bundle is built with `@mcp-b/webmcp-polyfill` external — the bridge's
|
|
39
|
+
// default `import("@mcp-b/webmcp-polyfill")` is a bare specifier no browser
|
|
40
|
+
// can resolve, so register a loader that imports the self-contained
|
|
41
|
+
// `webmcp-polyfill.js` chunk from a sibling URL instead. Mirrors how
|
|
42
|
+
// `install.ts` derives `launcher.global.js` from a `jsUrl` override.
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
import { setWebMcpPolyfillLoader } from "./webmcp-bridge";
|
|
46
|
+
|
|
47
|
+
// Capture at module-evaluation time — `document.currentScript` is null once
|
|
48
|
+
// execution leaves the script's initial synchronous run.
|
|
49
|
+
const widgetScriptSrc: string | null =
|
|
50
|
+
typeof document !== "undefined"
|
|
51
|
+
? ((document.currentScript as HTMLScriptElement | null)?.src ?? null)
|
|
52
|
+
: null;
|
|
53
|
+
|
|
54
|
+
setWebMcpPolyfillLoader(() => {
|
|
55
|
+
const chunkUrl = widgetScriptSrc?.replace(
|
|
56
|
+
/index\.global\.js($|\?)/,
|
|
57
|
+
"webmcp-polyfill.js$1",
|
|
58
|
+
);
|
|
59
|
+
if (!chunkUrl || chunkUrl === widgetScriptSrc) {
|
|
60
|
+
return Promise.reject(
|
|
61
|
+
new Error(
|
|
62
|
+
"Could not derive the webmcp-polyfill.js URL from the widget script URL " +
|
|
63
|
+
`(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
|
|
64
|
+
"rename index.global.js should install @mcp-b/webmcp-polyfill on the " +
|
|
65
|
+
"page themselves before enabling config.webmcp.",
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
// Runtime-only dynamic import; the specifier is a computed URL, so esbuild
|
|
70
|
+
// leaves it untouched (and must not try to bundle it).
|
|
71
|
+
return import(/* @vite-ignore */ chunkUrl);
|
|
72
|
+
});
|