@runtypelabs/persona 3.21.3 → 3.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +67 -0
  2. package/dist/animations/glyph-cycle.d.cts +1 -1
  3. package/dist/animations/glyph-cycle.d.ts +1 -1
  4. package/dist/animations/{types-CWPIj66R.d.cts → types-BZVr1YOV.d.cts} +10 -0
  5. package/dist/animations/{types-CWPIj66R.d.ts → types-BZVr1YOV.d.ts} +10 -0
  6. package/dist/animations/wipe.d.cts +1 -1
  7. package/dist/animations/wipe.d.ts +1 -1
  8. package/dist/index.cjs +50 -43
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +474 -6
  11. package/dist/index.d.ts +474 -6
  12. package/dist/index.global.js +98 -88
  13. package/dist/index.global.js.map +1 -1
  14. package/dist/index.js +48 -41
  15. package/dist/index.js.map +1 -1
  16. package/dist/smart-dom-reader.cjs +1875 -0
  17. package/dist/smart-dom-reader.d.cts +4521 -0
  18. package/dist/smart-dom-reader.d.ts +4521 -0
  19. package/dist/smart-dom-reader.js +1848 -0
  20. package/dist/theme-editor.cjs +2281 -84
  21. package/dist/theme-editor.d.cts +348 -1
  22. package/dist/theme-editor.d.ts +348 -1
  23. package/dist/theme-editor.js +2260 -78
  24. package/package.json +9 -2
  25. package/src/client.test.ts +165 -0
  26. package/src/client.ts +144 -23
  27. package/src/index.ts +26 -0
  28. package/src/session.test.ts +258 -0
  29. package/src/session.ts +886 -30
  30. package/src/session.webmcp.test.ts +815 -0
  31. package/src/smart-dom-reader.test.ts +135 -0
  32. package/src/smart-dom-reader.ts +135 -0
  33. package/src/theme-editor/color-utils.test.ts +59 -0
  34. package/src/theme-editor/color-utils.ts +38 -2
  35. package/src/theme-editor/index.ts +35 -0
  36. package/src/theme-editor/webmcp/coerce.test.ts +86 -0
  37. package/src/theme-editor/webmcp/coerce.ts +286 -0
  38. package/src/theme-editor/webmcp/index.ts +45 -0
  39. package/src/theme-editor/webmcp/summary.ts +324 -0
  40. package/src/theme-editor/webmcp/tools.test.ts +205 -0
  41. package/src/theme-editor/webmcp/tools.ts +795 -0
  42. package/src/theme-editor/webmcp/types.ts +87 -0
  43. package/src/types.ts +186 -0
  44. package/src/ui.composer-keyboard.test.ts +229 -0
  45. package/src/ui.ts +127 -5
  46. package/src/utils/composer-history.test.ts +128 -0
  47. package/src/utils/composer-history.ts +113 -0
  48. package/src/utils/message-fingerprint.test.ts +20 -0
  49. package/src/utils/message-fingerprint.ts +2 -0
  50. package/src/utils/smart-dom-adapter.test.ts +257 -0
  51. package/src/utils/smart-dom-adapter.ts +217 -0
  52. package/{LICENSE → src/vendor/smart-dom-reader/LICENSE} +2 -2
  53. package/src/vendor/smart-dom-reader/README.md +61 -0
  54. package/src/vendor/smart-dom-reader/index.d.ts +476 -0
  55. package/src/vendor/smart-dom-reader/index.js +1618 -0
  56. package/src/webmcp-bridge.test.ts +429 -0
  57. package/src/webmcp-bridge.ts +547 -0
@@ -771,6 +771,13 @@ type AgentWidgetRequestPayload = {
771
771
  metadata?: Record<string, unknown>;
772
772
  /** Per-turn template variables for /v1/client/chat (merged as root-level {{var}} in Runtype). */
773
773
  inputs?: Record<string, unknown>;
774
+ /**
775
+ * Per-turn page-discovered tools (WebMCP). Sent to Runtype's dispatch so the
776
+ * agent can call them as `webmcp:<name>`. The widget snapshots
777
+ * `document.modelContext.__getRegisteredTools()` each turn and ships only
778
+ * the JSON-serializable surface (no `execute`).
779
+ */
780
+ clientTools?: ClientToolDefinition[];
774
781
  };
775
782
  /**
776
783
  * Configuration for agent loop behavior.
@@ -846,6 +853,90 @@ type AgentRequestOptions = {
846
853
  /** Enable debug mode for additional event data */
847
854
  debugMode?: boolean;
848
855
  };
856
+ /**
857
+ * Wire shape for a single client-discovered tool sent on `dispatch.clientTools[]`.
858
+ *
859
+ * Mirrors the SDK's `ClientToolDefinition` in `@runtypelabs/sdk`. Only the
860
+ * JSON-serializable surface of a WebMCP tool — the `execute` function stays
861
+ * client-side; the server merges these into the agent's tool catalog under
862
+ * the `webmcp:` namespace.
863
+ */
864
+ type ClientToolDefinition = {
865
+ /** Bare tool name; the server prepends `webmcp:` on the wire. */
866
+ name: string;
867
+ description: string;
868
+ /** JSON Schema (per WebMCP spec) — passed through as-is. */
869
+ parametersSchema?: object;
870
+ /** Set to `'webmcp'` for tools discovered via the polyfill. */
871
+ origin?: 'webmcp' | 'local';
872
+ /** Origin of the page that registered the tool — for server-side audit. */
873
+ pageOrigin?: string;
874
+ /**
875
+ * WebMCP `Tool.annotations` (spec). Not used for gating server-side; the
876
+ * widget reads these client-side. Forwarded so traces/dashboards can show
877
+ * `readOnlyHint` / `untrustedContentHint` on tool-call records.
878
+ */
879
+ annotations?: {
880
+ readOnlyHint?: boolean;
881
+ untrustedContentHint?: boolean;
882
+ };
883
+ };
884
+ /**
885
+ * Information passed to the confirm-bubble handler before a `webmcp:*` tool
886
+ * call executes. Every WebMCP tool routes through this single gate.
887
+ */
888
+ type WebMcpConfirmInfo = {
889
+ /** Bare tool name (no `webmcp:` prefix). */
890
+ toolName: string;
891
+ args: unknown;
892
+ description?: string;
893
+ annotations?: {
894
+ readOnlyHint?: boolean;
895
+ untrustedContentHint?: boolean;
896
+ };
897
+ /**
898
+ * Why the confirm was requested. Currently always `'gate'` — the default
899
+ * confirm-by-default gate that fires before every `webmcp:*` call. (The
900
+ * `@mcp-b/webmcp-polyfill` owns the spec's `requestUserInteraction` callback
901
+ * internally, so Persona no longer surfaces a nested in-tool confirm.)
902
+ */
903
+ reason: 'gate';
904
+ };
905
+ /**
906
+ * Resolves to `true` if the user approves the tool call; `false` to decline.
907
+ */
908
+ type WebMcpConfirmHandler = (info: WebMcpConfirmInfo) => Promise<boolean>;
909
+ /**
910
+ * Widget-level WebMCP configuration. Set `enabled: true` to opt in. The
911
+ * surface's server-side `webmcp` policy is the source of truth for which
912
+ * tools are accepted — these client-side options are convenience filters.
913
+ */
914
+ type AgentWidgetWebMcpConfig = {
915
+ /** Master switch. Default: `false` (widget never installs the polyfill). */
916
+ enabled?: boolean;
917
+ /**
918
+ * Glob-ish name patterns to include client-side. `'*'` matches any chars
919
+ * except `:`. Patterns are matched against the bare tool name (no `webmcp:`
920
+ * prefix). If unset, all registered tools are included.
921
+ */
922
+ allowlist?: string[];
923
+ /**
924
+ * Per-tool gate policy. Called before the confirm gate for every
925
+ * `webmcp:*` call; return `true` to approve immediately and skip the
926
+ * confirmation UI entirely. Use this to auto-allow read-only tools (e.g.
927
+ * a catalog search) while still gating mutating ones. Only consulted on
928
+ * the default-UI path — a custom `onConfirm` takes full control instead.
929
+ */
930
+ autoApprove?: (info: WebMcpConfirmInfo) => boolean;
931
+ /**
932
+ * Confirm gate handler. When omitted, Persona renders its native in-panel
933
+ * approval bubble (the same chrome used for server-driven tool approvals)
934
+ * and resolves on the user's Approve/Deny click. Supply this to override
935
+ * with a custom confirmer (e.g. a route-level modal). The legacy
936
+ * `window.confirm` fallback only applies when no widget UI is attached.
937
+ */
938
+ onConfirm?: WebMcpConfirmHandler;
939
+ };
849
940
  /**
850
941
  * Metadata attached to messages created during agent execution.
851
942
  */
@@ -872,6 +963,16 @@ type AgentMessageMetadata = {
872
963
  * `POST /v1/dispatch/resume` with the user's answer keyed by tool name.
873
964
  */
874
965
  awaitingLocalTool?: boolean;
966
+ /**
967
+ * The provider per-call id (`toolu_…`) carried on the `step_await` /
968
+ * `flow_await` events for a LOCAL tool (core#3878). Present only when the
969
+ * server emits it. Two PARALLEL calls to the same tool in one turn share a
970
+ * `toolName` (and a collapsed `toolId`) but get DISTINCT `webMcpToolCallId`s,
971
+ * so this is the key the widget batches a single `/resume` on — preferred
972
+ * over tool name, which collides for same-tool parallel calls. Absent →
973
+ * fall back to the legacy name-keyed resume contract.
974
+ */
975
+ webMcpToolCallId?: string;
875
976
  /**
876
977
  * Set to `true` once the user has picked / typed / dismissed an answer for
877
978
  * an `ask_user_question` tool call, so renderers stop re-mounting the
@@ -1484,6 +1585,14 @@ type AgentWidgetFeatureFlags = {
1484
1585
  showReasoning?: boolean;
1485
1586
  showToolCalls?: boolean;
1486
1587
  showEventStreamToggle?: boolean;
1588
+ /**
1589
+ * Up/Down arrow navigation through previously sent user messages in the
1590
+ * composer, for quick re-entry or editing (shell / Slack style). History is
1591
+ * only entered when the caret is at the start of the input, so normal
1592
+ * multi-line cursor movement is preserved. Set to `false` to disable.
1593
+ * @default true
1594
+ */
1595
+ composerHistory?: boolean;
1487
1596
  /** Shared transcript + event stream scroll-to-bottom affordance. */
1488
1597
  scrollToBottom?: AgentWidgetScrollToBottomFeature;
1489
1598
  /** Collapsed transcript behavior for tool call rows. */
@@ -3269,6 +3378,31 @@ type AgentWidgetLoadingIndicatorConfig = {
3269
3378
  type AgentWidgetConfig = {
3270
3379
  apiUrl?: string;
3271
3380
  flowId?: string;
3381
+ /**
3382
+ * Override the assistant-bubble copy shown when a dispatch fails before any
3383
+ * response streams back (connection refused, CORS, 4xx/5xx, malformed
3384
+ * stream). Provide a static string, or a function of the error so you can
3385
+ * tailor the message per failure and decide whether to surface the raw
3386
+ * reason. When omitted, a default message is shown that includes the
3387
+ * underlying error detail.
3388
+ *
3389
+ * Returning an empty string suppresses the fallback bubble entirely (the
3390
+ * `onError` callback still fires).
3391
+ *
3392
+ * @example
3393
+ * ```typescript
3394
+ * config: {
3395
+ * // Static
3396
+ * errorMessage: "We're having trouble connecting. Please try again."
3397
+ * // Or dynamic
3398
+ * errorMessage: (error) =>
3399
+ * error.message.includes("Failed to fetch")
3400
+ * ? "You appear to be offline."
3401
+ * : "Something went wrong. Please try again."
3402
+ * }
3403
+ * ```
3404
+ */
3405
+ errorMessage?: string | ((error: Error) => string);
3272
3406
  /**
3273
3407
  * Agent configuration for agent execution mode.
3274
3408
  * When provided, the widget uses agent loop execution instead of flow dispatch.
@@ -3500,6 +3634,26 @@ type AgentWidgetConfig = {
3500
3634
  * ```
3501
3635
  */
3502
3636
  approval?: AgentWidgetApprovalConfig | false;
3637
+ /**
3638
+ * WebMCP — consume page-registered tools (`document.modelContext.registerTool`).
3639
+ * When `enabled`, the widget installs `@mcp-b/webmcp-polyfill`, snapshots the
3640
+ * registry on every dispatch, ships it as `clientTools[]`, and executes
3641
+ * returned `webmcp:*` tool calls with confirm-by-default gating.
3642
+ *
3643
+ * Server-side policy on the chat surface is the source of truth — these
3644
+ * fields layer on top.
3645
+ *
3646
+ * @example
3647
+ * ```typescript
3648
+ * config: {
3649
+ * webmcp: {
3650
+ * enabled: true,
3651
+ * allowlist: ['search_*', 'list_*'],
3652
+ * }
3653
+ * }
3654
+ * ```
3655
+ */
3656
+ webmcp?: AgentWidgetWebMcpConfig;
3503
3657
  postprocessMessage?: (context: {
3504
3658
  text: string;
3505
3659
  message: AgentWidgetMessage;
@@ -4854,6 +5008,14 @@ declare function convertToPx(value: number, unit: 'px' | 'rem'): number;
4854
5008
  declare function convertFromPx(pxValue: number, unit: 'px' | 'rem'): number;
4855
5009
  declare function normalizeColorValue(value: string): string;
4856
5010
  declare function isValidHex(value: string): boolean;
5011
+ /**
5012
+ * Parse an `rgb()` / `rgba()` string into `#rrggbb`. Accepts integer (0-255) or
5013
+ * percentage channels; any alpha component is dropped. Returns `null` when the
5014
+ * string is not a parseable rgb/rgba value, so callers can fall back. This lets
5015
+ * the HSL/luminance paths — which otherwise `parseInt` hex digits — accept the
5016
+ * `rgb()` inputs that `coerceColor` admits without producing `#NaNNaNNaN`.
5017
+ */
5018
+ declare function rgbToHex(value: string): string | null;
4857
5019
  /**
4858
5020
  * Compute WCAG 2.x contrast ratio between two hex colors.
4859
5021
  * Returns a number ≥ 1 (e.g. 4.5 for AA normal text).
@@ -4880,4 +5042,189 @@ declare function paletteColorPath(family: string, shade: string): string;
4880
5042
  declare function resolveThemeColorPath(get: (path: string) => unknown, path: string, depth?: number): string;
4881
5043
  declare function tokenRefDisplayName(path: string): string;
4882
5044
 
4883
- export { ADVANCED_TOKENS_SECTION, ALL_ROLES, ALL_TABS, BRAND_PALETTE_SECTION, BUILT_IN_PRESETS, type BuildTranscriptStreamFramesOptions, COLORS_SECTIONS, COLOR_FAMILIES, COMPONENTS_SECTIONS, COMPONENT_COLOR_SECTIONS, COMPONENT_SHAPE_SECTIONS, CONFIGURE_SECTIONS, CONFIGURE_SUB_GROUPS, type ColorScaleOptions, type CompareMode, type ConfigChangeListener, type ConfiguratorSnapshot, DEVICE_DIMENSIONS, type DetectedRoleAssignment, type FieldDef, type FieldType, HOME_SUGGESTION_CHIPS, INTERFACE_ROLES_SECTION, MOCK_BROWSER_CONTENT, MOCK_WORKSPACE_CONTENT, type OnChangeCallback, PALETTE_SECTION, PREVIEW_STORAGE_ADAPTER, type PreviewConfigOptions, type PreviewDevice, type PreviewLifecycleContext, type PreviewScene, type PreviewShellMode, type PreviewShellPalette, type PreviewTranscriptEntryPreset, ROLE_ASSISTANT_MESSAGES, ROLE_BORDERS, ROLE_FAMILIES, ROLE_FAMILY_LABELS, ROLE_HEADER, ROLE_INPUT, ROLE_INTENSITIES, ROLE_LINKS_FOCUS, ROLE_PRIMARY_ACTIONS, ROLE_SCROLL_TO_BOTTOM, ROLE_SURFACES, ROLE_USER_MESSAGES, type RoleAssignmentOptions, type RoleFamily, type RoleIntensity, type RoleTarget, type RoleTargetKind, SEMANTIC_COLORS_SECTION, SHADE_KEYS, SHELL_STYLE_ID, STATUS_COLORS_SECTION, STATUS_PALETTE_SECTION, STYLE_SECTIONS, STYLE_SECTIONS_V2, type SectionDef, type SectionPreset, type SelectOption, type SliderOptions, type SubGroupDef, THEME_EDITOR_PRESETS, THEME_SECTION, type TabDef, type ThemeEditorPreset, ThemeEditorState, type ThemePreviewHandle, type ThemePreviewOptions, type TokenRefOptions, type TranscriptStreamFrame, ZOOM_MAX, ZOOM_MIN, appendPreviewTranscriptEntry, applySceneConfig, applyShellTheme, buildPreviewConfig, buildPreviewConfigWithMessages, buildShellCss, buildSrcdoc, buildTranscriptStreamFrames, convertFromPx, convertToPx, createPreviewMessages, createPreviewTranscriptEntry, createThemePreview, detectRoleAssignment, escapeHtml, findSection, formatCssValue, generateColorScale, getPreviewTranscriptPresetLabel, getShellPalette, getThemeEditorPreset, hexToHsl, hslToHex, isValidHex, normalizeColorValue, paletteColorPath, parseCssValue, presetStreamsText, resolveRoleAssignment, resolveThemeColorPath, scopeSection, tokenRefDisplayName, wcagContrastRatio };
5045
+ /**
5046
+ * Minimal local typings for the WebMCP `document.modelContext` surface, plus the
5047
+ * structural state interface the tool factory operates on.
5048
+ *
5049
+ * We deliberately keep our own small WebMCP types rather than depending on
5050
+ * `@mcp-b/webmcp-types`, so the tool definitions are transport-agnostic and the
5051
+ * widget package takes on no polyfill dependency. These mirror the WebMCP draft
5052
+ * (`registerTool(tool, { signal })`) and the MCP tool-result envelope that
5053
+ * `@mcp-b/webmcp-polyfill` expects `execute` to return.
5054
+ */
5055
+
5056
+ interface ToolTextContent {
5057
+ type: 'text';
5058
+ text: string;
5059
+ }
5060
+ interface ToolResult {
5061
+ content: ToolTextContent[];
5062
+ /** Optional machine-readable mirror of the text content. */
5063
+ structuredContent?: unknown;
5064
+ isError?: boolean;
5065
+ }
5066
+ interface ToolAnnotations {
5067
+ /** The tool has no side effects (pure read). */
5068
+ readOnlyHint?: boolean;
5069
+ /** The tool's output may contain text not to be trusted as instructions. */
5070
+ untrustedContentHint?: boolean;
5071
+ }
5072
+ type ToolExecute = (input: unknown) => Promise<ToolResult> | ToolResult;
5073
+ interface WebMcpTool {
5074
+ name: string;
5075
+ description: string;
5076
+ title?: string;
5077
+ inputSchema?: object;
5078
+ annotations?: ToolAnnotations;
5079
+ execute: ToolExecute;
5080
+ }
5081
+ /** Wrap a JSON-serializable payload in the MCP tool-result envelope. */
5082
+ declare function toolResult(payload: unknown): ToolResult;
5083
+ /**
5084
+ * Structural subset of `ThemeEditorState` (and the example app's `state`
5085
+ * module) that the tools require. Anything satisfying this shape can be wired
5086
+ * to the tools — the headless `ThemeEditorState`, or a host's stateful wrapper
5087
+ * that also drives a live preview (e.g. a Persona widget styling itself).
5088
+ */
5089
+ interface ThemeEditorLike {
5090
+ get(path: string): unknown;
5091
+ set(path: string, value: unknown): void;
5092
+ setBatch(updates: Record<string, unknown>): void;
5093
+ setTheme(theme: PersonaTheme): void;
5094
+ setFullConfig(config: AgentWidgetConfig, theme?: PersonaTheme): void;
5095
+ undo(): void;
5096
+ redo(): void;
5097
+ canUndo(): boolean;
5098
+ canRedo(): boolean;
5099
+ getHistoryIndex(): number;
5100
+ getTheme(): PersonaTheme;
5101
+ getConfig(): AgentWidgetConfig;
5102
+ exportSnapshot(): ConfiguratorSnapshot;
5103
+ resetToDefaults(): void;
5104
+ }
5105
+ /** Which theme variant(s) styling tools write to. */
5106
+ type EditTarget = 'light' | 'dark' | 'both';
5107
+ interface CreateThemeEditorToolsOptions {
5108
+ /** Default variant for styling writes. Defaults to `'both'`. */
5109
+ editTarget?: EditTarget;
5110
+ }
5111
+
5112
+ /**
5113
+ * WebMCP tool factory for the Persona theme editor.
5114
+ *
5115
+ * `createThemeEditorTools(state)` returns transport-agnostic tool definitions
5116
+ * designed for Agent Experience: intent-level operations (set brand colors,
5117
+ * assign a color role, set roundness…) rather than a 1:1 mapping of the ~150
5118
+ * editor fields. Two altitudes — high-level semantic tools plus a low-level
5119
+ * escape hatch (`set_theme_fields`) — keep the catalog small without losing
5120
+ * coverage. Every mutation returns a compact summary + contrast warnings.
5121
+ */
5122
+
5123
+ declare function createThemeEditorTools(state: ThemeEditorLike, options?: CreateThemeEditorToolsOptions): WebMcpTool[];
5124
+
5125
+ /**
5126
+ * Input coercion for the WebMCP theme tools.
5127
+ *
5128
+ * Agent inputs are flexible by design (arcade.dev "parameter coercion"): colors
5129
+ * accept hex with/without `#`, 3-digit hex, rgb(), and common CSS color names;
5130
+ * enums accept friendly synonyms. Each coercer throws an Error whose message
5131
+ * lists the valid options (arcade.dev "error-guided recovery").
5132
+ */
5133
+ declare const CSS_NAMED_COLORS: Record<string, string>;
5134
+ /**
5135
+ * Coerce a flexible color input into a canonical CSS color string.
5136
+ * Accepts: `#1d4ed8`, `1d4ed8`, `#18f`, `rgb(...)`, `transparent`, and common
5137
+ * CSS color names. Throws with guidance when the value can't be understood.
5138
+ */
5139
+ declare function coerceColor(input: unknown): string;
5140
+ type BrandFamily = 'primary' | 'secondary' | 'accent';
5141
+ type RoleFamilyInput = BrandFamily | 'neutral';
5142
+ /** Coerce a palette family. Set `allowNeutral` for role assignments. */
5143
+ declare function coerceFamily(input: unknown, allowNeutral?: boolean): RoleFamilyInput;
5144
+ declare function coerceIntensity(input: unknown): 'solid' | 'soft';
5145
+ declare function coerceScheme(input: unknown): 'light' | 'dark' | 'auto';
5146
+ type RoundnessStyle = 'sharp' | 'default' | 'rounded' | 'pill';
5147
+ declare function coerceRoundnessStyle(input: unknown): RoundnessStyle;
5148
+ /** Coerce a radius value: numbers become `${n}px`; CSS strings are normalized. */
5149
+ declare function coerceRadius(input: unknown): string;
5150
+
5151
+ /**
5152
+ * Theme state summarization + contrast feedback for the WebMCP tools.
5153
+ *
5154
+ * Every mutation tool returns a compact `ThemeSummary` plus any contrast
5155
+ * warnings, so an agent gets actionable feedback without a follow-up read
5156
+ * (arcade.dev "proactive state-returning").
5157
+ */
5158
+
5159
+ declare const RADIUS_PRESETS: Record<string, Record<string, string>>;
5160
+ interface RoleState {
5161
+ family: string;
5162
+ intensity: string;
5163
+ }
5164
+ interface ThemeSummary {
5165
+ brand: {
5166
+ primary: string | null;
5167
+ secondary: string | null;
5168
+ accent: string | null;
5169
+ };
5170
+ roles: Record<string, RoleState | null>;
5171
+ typography: {
5172
+ fontFamily: string;
5173
+ fontSize: string;
5174
+ fontWeight: string;
5175
+ lineHeight: string;
5176
+ };
5177
+ roundness: {
5178
+ style: RoundnessStyle | 'custom';
5179
+ radius: Record<string, string>;
5180
+ };
5181
+ colorScheme: string;
5182
+ history: {
5183
+ index: number;
5184
+ canUndo: boolean;
5185
+ canRedo: boolean;
5186
+ };
5187
+ }
5188
+ declare function buildSummary(state: ThemeEditorLike): ThemeSummary;
5189
+ interface ContrastPair {
5190
+ key: string;
5191
+ label: string;
5192
+ fg: string;
5193
+ bg: string;
5194
+ }
5195
+ declare const CONTRAST_PAIRS: ContrastPair[];
5196
+ interface ContrastWarning {
5197
+ code: 'contrast';
5198
+ pair: string;
5199
+ variant: 'light' | 'dark';
5200
+ ratio: number;
5201
+ threshold: number;
5202
+ message: string;
5203
+ }
5204
+ declare const CONTRAST_THRESHOLDS: {
5205
+ readonly AA: 4.5;
5206
+ readonly AAA: 7;
5207
+ };
5208
+ type ContrastLevel = keyof typeof CONTRAST_THRESHOLDS;
5209
+ interface ContrastCheck {
5210
+ pair: string;
5211
+ label: string;
5212
+ variant: 'light' | 'dark';
5213
+ fg: string;
5214
+ bg: string;
5215
+ ratio: number;
5216
+ threshold: number;
5217
+ passes: boolean;
5218
+ suggestion?: string;
5219
+ }
5220
+ interface ContrastReport {
5221
+ level: ContrastLevel;
5222
+ checks: ContrastCheck[];
5223
+ failures: ContrastCheck[];
5224
+ }
5225
+ /** Run contrast over the named pairs (default: all) for the given variant(s). */
5226
+ declare function runContrastChecks(state: ThemeEditorLike, level?: ContrastLevel, variant?: 'light' | 'dark' | 'both', pairKeys?: string[]): ContrastReport;
5227
+ /** Compact contrast warnings for the regions a mutation touched. */
5228
+ declare function quickContrastWarnings(state: ThemeEditorLike, pairKeys: string[], variant?: 'light' | 'dark' | 'both', level?: ContrastLevel): ContrastWarning[];
5229
+
5230
+ export { ADVANCED_TOKENS_SECTION, ALL_ROLES, ALL_TABS, BRAND_PALETTE_SECTION, BUILT_IN_PRESETS, type BuildTranscriptStreamFramesOptions, COLORS_SECTIONS, COLOR_FAMILIES, COMPONENTS_SECTIONS, COMPONENT_COLOR_SECTIONS, COMPONENT_SHAPE_SECTIONS, CONFIGURE_SECTIONS, CONFIGURE_SUB_GROUPS, CONTRAST_PAIRS, CSS_NAMED_COLORS, type ColorScaleOptions, type CompareMode, type ConfigChangeListener, type ConfiguratorSnapshot, type ContrastCheck, type ContrastLevel, type ContrastReport, type ContrastWarning, type CreateThemeEditorToolsOptions, DEVICE_DIMENSIONS, type DetectedRoleAssignment, type EditTarget, type FieldDef, type FieldType, HOME_SUGGESTION_CHIPS, INTERFACE_ROLES_SECTION, MOCK_BROWSER_CONTENT, MOCK_WORKSPACE_CONTENT, type OnChangeCallback, PALETTE_SECTION, PREVIEW_STORAGE_ADAPTER, type PreviewConfigOptions, type PreviewDevice, type PreviewLifecycleContext, type PreviewScene, type PreviewShellMode, type PreviewShellPalette, type PreviewTranscriptEntryPreset, RADIUS_PRESETS, ROLE_ASSISTANT_MESSAGES, ROLE_BORDERS, ROLE_FAMILIES, ROLE_FAMILY_LABELS, ROLE_HEADER, ROLE_INPUT, ROLE_INTENSITIES, ROLE_LINKS_FOCUS, ROLE_PRIMARY_ACTIONS, ROLE_SCROLL_TO_BOTTOM, ROLE_SURFACES, ROLE_USER_MESSAGES, type RoleAssignmentOptions, type RoleFamily, type RoleIntensity, type RoleState, type RoleTarget, type RoleTargetKind, SEMANTIC_COLORS_SECTION, SHADE_KEYS, SHELL_STYLE_ID, STATUS_COLORS_SECTION, STATUS_PALETTE_SECTION, STYLE_SECTIONS, STYLE_SECTIONS_V2, type SectionDef, type SectionPreset, type SelectOption, type SliderOptions, type SubGroupDef, THEME_EDITOR_PRESETS, THEME_SECTION, type TabDef, type ThemeEditorLike, type ThemeEditorPreset, ThemeEditorState, type ThemePreviewHandle, type ThemePreviewOptions, type ThemeSummary, type TokenRefOptions, type ToolAnnotations, type ToolExecute, type ToolResult, type ToolTextContent, type TranscriptStreamFrame, type WebMcpTool, ZOOM_MAX, ZOOM_MIN, appendPreviewTranscriptEntry, applySceneConfig, applyShellTheme, buildPreviewConfig, buildPreviewConfigWithMessages, buildShellCss, buildSrcdoc, buildSummary, buildTranscriptStreamFrames, coerceColor, coerceFamily, coerceIntensity, coerceRadius, coerceRoundnessStyle, coerceScheme, convertFromPx, convertToPx, createPreviewMessages, createPreviewTranscriptEntry, createThemeEditorTools, createThemePreview, detectRoleAssignment, escapeHtml, findSection, formatCssValue, generateColorScale, getPreviewTranscriptPresetLabel, getShellPalette, getThemeEditorPreset, hexToHsl, hslToHex, isValidHex, normalizeColorValue, paletteColorPath, parseCssValue, presetStreamsText, quickContrastWarnings, resolveRoleAssignment, resolveThemeColorPath, rgbToHex, runContrastChecks, scopeSection, tokenRefDisplayName, toolResult, wcagContrastRatio };