@runtypelabs/persona 1.48.0 → 2.0.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 (69) hide show
  1. package/README.md +140 -8
  2. package/dist/index.cjs +90 -39
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +1055 -24
  5. package/dist/index.d.ts +1055 -24
  6. package/dist/index.global.js +111 -60
  7. package/dist/index.global.js.map +1 -1
  8. package/dist/index.js +90 -39
  9. package/dist/index.js.map +1 -1
  10. package/dist/install.global.js +1 -1
  11. package/dist/install.global.js.map +1 -1
  12. package/dist/widget.css +836 -513
  13. package/package.json +1 -1
  14. package/src/artifacts-session.test.ts +80 -0
  15. package/src/client.test.ts +20 -21
  16. package/src/client.ts +153 -4
  17. package/src/components/approval-bubble.ts +45 -42
  18. package/src/components/artifact-card.ts +91 -0
  19. package/src/components/artifact-pane.ts +501 -0
  20. package/src/components/composer-builder.ts +32 -27
  21. package/src/components/event-stream-view.ts +40 -40
  22. package/src/components/feedback.ts +36 -36
  23. package/src/components/forms.ts +11 -11
  24. package/src/components/header-builder.test.ts +32 -0
  25. package/src/components/header-builder.ts +55 -36
  26. package/src/components/header-layouts.ts +58 -125
  27. package/src/components/launcher.ts +36 -21
  28. package/src/components/message-bubble.ts +92 -65
  29. package/src/components/messages.ts +2 -2
  30. package/src/components/panel.ts +42 -11
  31. package/src/components/reasoning-bubble.ts +23 -23
  32. package/src/components/registry.ts +4 -0
  33. package/src/components/suggestions.ts +1 -1
  34. package/src/components/tool-bubble.ts +32 -32
  35. package/src/defaults.ts +30 -4
  36. package/src/index.ts +80 -2
  37. package/src/install.ts +22 -0
  38. package/src/plugins/types.ts +23 -0
  39. package/src/postprocessors.ts +2 -2
  40. package/src/runtime/host-layout.ts +174 -0
  41. package/src/runtime/init.test.ts +236 -0
  42. package/src/runtime/init.ts +114 -55
  43. package/src/session.ts +135 -2
  44. package/src/styles/tailwind.css +1 -1
  45. package/src/styles/widget.css +836 -513
  46. package/src/types/theme.ts +354 -0
  47. package/src/types.ts +314 -15
  48. package/src/ui.docked.test.ts +104 -0
  49. package/src/ui.ts +940 -227
  50. package/src/utils/artifact-gate.test.ts +255 -0
  51. package/src/utils/artifact-gate.ts +142 -0
  52. package/src/utils/artifact-resize.test.ts +64 -0
  53. package/src/utils/artifact-resize.ts +67 -0
  54. package/src/utils/attachment-manager.ts +10 -10
  55. package/src/utils/code-generators.test.ts +52 -0
  56. package/src/utils/code-generators.ts +40 -36
  57. package/src/utils/dock.ts +17 -0
  58. package/src/utils/dom-context.test.ts +504 -0
  59. package/src/utils/dom-context.ts +896 -0
  60. package/src/utils/dom.ts +12 -1
  61. package/src/utils/message-fingerprint.test.ts +187 -0
  62. package/src/utils/message-fingerprint.ts +105 -0
  63. package/src/utils/migration.ts +179 -0
  64. package/src/utils/morph.ts +1 -1
  65. package/src/utils/plugins.ts +175 -0
  66. package/src/utils/positioning.ts +4 -4
  67. package/src/utils/theme.test.ts +125 -0
  68. package/src/utils/theme.ts +216 -60
  69. package/src/utils/tokens.ts +682 -0
@@ -66,26 +66,28 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
66
66
 
67
67
  const footer = createElement(
68
68
  "div",
69
- "tvw-widget-footer tvw-border-t-cw-divider tvw-bg-cw-surface tvw-px-6 tvw-py-4"
69
+ "persona-widget-footer persona-border-t-persona-divider persona-bg-persona-surface persona-px-6 persona-py-4"
70
70
  );
71
71
 
72
72
  const suggestions = createElement(
73
73
  "div",
74
- "tvw-mb-3 tvw-flex tvw-flex-wrap tvw-gap-2"
74
+ "persona-mb-3 persona-flex persona-flex-wrap persona-gap-2"
75
75
  );
76
76
 
77
77
  // Composer form uses column layout: textarea on top, actions row below
78
78
  const composerForm = createElement(
79
79
  "form",
80
- `tvw-widget-composer tvw-flex tvw-flex-col tvw-gap-2 tvw-rounded-2xl tvw-border tvw-border-gray-200 tvw-bg-cw-input-background tvw-px-4 tvw-py-3`
80
+ `persona-widget-composer persona-flex persona-flex-col persona-gap-2 persona-rounded-2xl persona-border persona-border-gray-200 persona-bg-persona-input-background persona-px-4 persona-py-3`
81
81
  ) as HTMLFormElement;
82
+ composerForm.setAttribute("data-persona-composer-form", "");
82
83
  // Prevent form from getting focus styles
83
84
  composerForm.style.outline = "none";
84
85
 
85
86
  const textarea = createElement("textarea") as HTMLTextAreaElement;
87
+ textarea.setAttribute("data-persona-composer-input", "");
86
88
  textarea.placeholder = config?.copy?.inputPlaceholder ?? "Type your message…";
87
89
  textarea.className =
88
- "tvw-w-full tvw-min-h-[24px] tvw-resize-none tvw-border-none tvw-bg-transparent tvw-text-sm tvw-text-cw-primary focus:tvw-outline-none focus:tvw-border-none tvw-composer-textarea";
90
+ "persona-w-full persona-min-h-[24px] persona-resize-none persona-border-none persona-bg-transparent persona-text-sm persona-text-persona-primary focus:persona-outline-none focus:persona-border-none persona-composer-textarea";
89
91
  textarea.rows = 1;
90
92
 
91
93
  // Apply font family and weight from config
@@ -146,16 +148,17 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
146
148
  const textColor = sendButtonConfig.textColor;
147
149
 
148
150
  // Create wrapper for tooltip positioning
149
- const sendButtonWrapper = createElement("div", "tvw-send-button-wrapper");
151
+ const sendButtonWrapper = createElement("div", "persona-send-button-wrapper");
150
152
 
151
153
  const sendButton = createElement(
152
154
  "button",
153
155
  useIcon
154
- ? "tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer"
155
- : "tvw-rounded-button tvw-bg-cw-accent tvw-px-4 tvw-py-2 tvw-text-sm tvw-font-semibold disabled:tvw-opacity-50 tvw-cursor-pointer"
156
+ ? "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
157
+ : "persona-rounded-button persona-bg-persona-accent persona-px-4 persona-py-2 persona-text-sm persona-font-semibold disabled:persona-opacity-50 persona-cursor-pointer"
156
158
  ) as HTMLButtonElement;
157
159
 
158
160
  sendButton.type = "submit";
161
+ sendButton.setAttribute("data-persona-composer-submit", "");
159
162
 
160
163
  if (useIcon) {
161
164
  // Icon mode: circular button
@@ -186,7 +189,7 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
186
189
  if (textColor) {
187
190
  sendButton.style.color = textColor;
188
191
  } else {
189
- sendButton.classList.add("tvw-text-white");
192
+ sendButton.classList.add("persona-text-white");
190
193
  }
191
194
  }
192
195
  } else {
@@ -194,14 +197,14 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
194
197
  if (textColor) {
195
198
  sendButton.style.color = textColor;
196
199
  } else {
197
- sendButton.classList.add("tvw-text-white");
200
+ sendButton.classList.add("persona-text-white");
198
201
  }
199
202
  }
200
203
 
201
204
  if (backgroundColor) {
202
205
  sendButton.style.backgroundColor = backgroundColor;
203
206
  } else {
204
- sendButton.classList.add("tvw-bg-cw-primary");
207
+ sendButton.classList.add("persona-bg-persona-primary");
205
208
  }
206
209
  } else {
207
210
  // Text mode: existing behavior
@@ -209,7 +212,7 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
209
212
  if (textColor) {
210
213
  sendButton.style.color = textColor;
211
214
  } else {
212
- sendButton.classList.add("tvw-text-white");
215
+ sendButton.classList.add("persona-text-white");
213
216
  }
214
217
  }
215
218
 
@@ -240,7 +243,7 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
240
243
 
241
244
  // Add tooltip if enabled
242
245
  if (showTooltip && tooltipText) {
243
- const tooltip = createElement("div", "tvw-send-button-tooltip");
246
+ const tooltip = createElement("div", "persona-send-button-tooltip");
244
247
  tooltip.textContent = tooltipText;
245
248
  sendButtonWrapper.appendChild(tooltip);
246
249
  }
@@ -263,13 +266,14 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
263
266
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
264
267
 
265
268
  if (voiceRecognitionEnabled && hasVoiceInput) {
266
- micButtonWrapper = createElement("div", "tvw-send-button-wrapper");
269
+ micButtonWrapper = createElement("div", "persona-send-button-wrapper");
267
270
  micButton = createElement(
268
271
  "button",
269
- "tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer"
272
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer"
270
273
  ) as HTMLButtonElement;
271
274
 
272
275
  micButton.type = "button";
276
+ micButton.setAttribute("data-persona-composer-mic", "");
273
277
  micButton.setAttribute("aria-label", "Start voice recognition");
274
278
 
275
279
  const micIconName = voiceRecognitionConfig.iconName ?? "mic";
@@ -309,14 +313,14 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
309
313
  if (micBackgroundColor) {
310
314
  micButton.style.backgroundColor = micBackgroundColor;
311
315
  } else {
312
- micButton.classList.add("tvw-bg-cw-primary");
316
+ micButton.classList.add("persona-bg-persona-primary");
313
317
  }
314
318
 
315
319
  // Apply icon/text color
316
320
  if (micIconColor) {
317
321
  micButton.style.color = micIconColor;
318
322
  } else if (!micIconColor && !textColor) {
319
- micButton.classList.add("tvw-text-white");
323
+ micButton.classList.add("persona-text-white");
320
324
  }
321
325
 
322
326
  // Apply border styling
@@ -345,7 +349,7 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
345
349
  voiceRecognitionConfig.tooltipText ?? "Start voice recognition";
346
350
  const showMicTooltip = voiceRecognitionConfig.showTooltip ?? false;
347
351
  if (showMicTooltip && micTooltipText) {
348
- const tooltip = createElement("div", "tvw-send-button-tooltip");
352
+ const tooltip = createElement("div", "persona-send-button-tooltip");
349
353
  tooltip.textContent = micTooltipText;
350
354
  micButtonWrapper.appendChild(tooltip);
351
355
  }
@@ -363,7 +367,7 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
363
367
  // Create previews container (shown above textarea when attachments are added)
364
368
  attachmentPreviewsContainer = createElement(
365
369
  "div",
366
- "tvw-attachment-previews tvw-flex tvw-flex-wrap tvw-gap-2 tvw-mb-2"
370
+ "persona-attachment-previews persona-flex persona-flex-wrap persona-gap-2 persona-mb-2"
367
371
  );
368
372
  attachmentPreviewsContainer.style.display = "none"; // Hidden until attachments added
369
373
 
@@ -376,12 +380,12 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
376
380
  attachmentInput.setAttribute("aria-label", "Attach files");
377
381
 
378
382
  // Create attachment button wrapper for tooltip
379
- attachmentButtonWrapper = createElement("div", "tvw-send-button-wrapper");
383
+ attachmentButtonWrapper = createElement("div", "persona-send-button-wrapper");
380
384
 
381
385
  // Create attachment button
382
386
  attachmentButton = createElement(
383
387
  "button",
384
- "tvw-rounded-button tvw-flex tvw-items-center tvw-justify-center disabled:tvw-opacity-50 tvw-cursor-pointer tvw-attachment-button"
388
+ "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
385
389
  ) as HTMLButtonElement;
386
390
  attachmentButton.type = "button";
387
391
  attachmentButton.setAttribute("aria-label", attachmentsConfig.buttonTooltipText ?? "Attach file");
@@ -400,14 +404,14 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
400
404
  attachmentButton.style.fontSize = "18px";
401
405
  attachmentButton.style.lineHeight = "1";
402
406
  attachmentButton.style.backgroundColor = "transparent";
403
- attachmentButton.style.color = "var(--cw-primary, #111827)";
407
+ attachmentButton.style.color = "var(--persona-primary, #111827)";
404
408
  attachmentButton.style.border = "none";
405
409
  attachmentButton.style.borderRadius = "6px";
406
410
  attachmentButton.style.transition = "background-color 0.15s ease";
407
411
 
408
412
  // Add hover effect via mouseenter/mouseleave
409
413
  attachmentButton.addEventListener("mouseenter", () => {
410
- attachmentButton!.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
414
+ attachmentButton!.style.backgroundColor = "var(--persona-palette-colors-black-alpha-50, rgba(0, 0, 0, 0.05))";
411
415
  });
412
416
  attachmentButton.addEventListener("mouseleave", () => {
413
417
  attachmentButton!.style.backgroundColor = "transparent";
@@ -436,7 +440,7 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
436
440
 
437
441
  // Add tooltip if configured
438
442
  const attachTooltipText = attachmentsConfig.buttonTooltipText ?? "Attach file";
439
- const tooltip = createElement("div", "tvw-send-button-tooltip");
443
+ const tooltip = createElement("div", "persona-send-button-tooltip");
440
444
  tooltip.textContent = attachTooltipText;
441
445
  attachmentButtonWrapper.appendChild(tooltip);
442
446
  }
@@ -477,16 +481,16 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
477
481
  composerForm.append(textarea);
478
482
 
479
483
  // Actions row: attachment on left, mic/send on right
480
- const actionsRow = createElement("div", "tvw-flex tvw-items-center tvw-justify-between tvw-w-full");
484
+ const actionsRow = createElement("div", "persona-flex persona-items-center persona-justify-between persona-w-full");
481
485
 
482
486
  // Left side: attachment button
483
- const leftActions = createElement("div", "tvw-flex tvw-items-center tvw-gap-2");
487
+ const leftActions = createElement("div", "persona-flex persona-items-center persona-gap-2");
484
488
  if (attachmentButtonWrapper) {
485
489
  leftActions.append(attachmentButtonWrapper);
486
490
  }
487
491
 
488
492
  // Right side: mic and send buttons
489
- const rightActions = createElement("div", "tvw-flex tvw-items-center tvw-gap-1");
493
+ const rightActions = createElement("div", "persona-flex persona-items-center persona-gap-1");
490
494
  if (micButtonWrapper) {
491
495
  rightActions.append(micButtonWrapper);
492
496
  }
@@ -497,8 +501,9 @@ export const buildComposer = (context: ComposerBuildContext): ComposerElements =
497
501
 
498
502
  const statusText = createElement(
499
503
  "div",
500
- "tvw-mt-2 tvw-text-right tvw-text-xs tvw-text-cw-muted"
504
+ "persona-mt-2 persona-text-right persona-text-xs persona-text-persona-muted"
501
505
  );
506
+ statusText.setAttribute("data-persona-composer-status", "");
502
507
 
503
508
  // Apply status indicator config
504
509
  const statusConfig = config?.statusIndicator ?? {};
@@ -25,16 +25,16 @@ function applyCustomClasses(el: HTMLElement, classes?: string): void {
25
25
  // ============================================================================
26
26
 
27
27
  const DEFAULT_BADGE_COLORS: Record<string, EventStreamBadgeColor> = {
28
- flow_: { bg: "#dcfce7", text: "#166534" },
29
- step_: { bg: "#dbeafe", text: "#1e40af" },
30
- reason_: { bg: "#ffedd5", text: "#9a3412" },
31
- tool_: { bg: "#f3e8ff", text: "#6b21a8" },
32
- agent_: { bg: "#ccfbf1", text: "#115e59" },
33
- error: { bg: "#fecaca", text: "#991b1b" },
28
+ flow_: { bg: "var(--persona-palette-colors-success-100, #dcfce7)", text: "var(--persona-palette-colors-success-700, #166534)" },
29
+ step_: { bg: "var(--persona-palette-colors-primary-100, #dbeafe)", text: "var(--persona-palette-colors-primary-700, #1e40af)" },
30
+ reason_: { bg: "var(--persona-palette-colors-warning-100, #ffedd5)", text: "var(--persona-palette-colors-warning-700, #9a3412)" },
31
+ tool_: { bg: "var(--persona-palette-colors-purple-100, #f3e8ff)", text: "var(--persona-palette-colors-purple-700, #6b21a8)" },
32
+ agent_: { bg: "var(--persona-palette-colors-teal-100, #ccfbf1)", text: "var(--persona-palette-colors-teal-700, #115e59)" },
33
+ error: { bg: "var(--persona-palette-colors-error-100, #fecaca)", text: "var(--persona-palette-colors-error-700, #991b1b)" },
34
34
  };
35
35
  const DEFAULT_BADGE_COLOR: EventStreamBadgeColor = {
36
- bg: "#f3f4f6",
37
- text: "#4b5563",
36
+ bg: "var(--persona-palette-colors-gray-100, #f3f4f6)",
37
+ text: "var(--persona-palette-colors-gray-600, #4b5563)",
38
38
  };
39
39
 
40
40
  const DEFAULT_DESCRIPTION_FIELDS = [
@@ -181,12 +181,12 @@ function renderInlinePayload(
181
181
  function renderDefaultPayload(): HTMLElement {
182
182
  const payloadContainer = createElement(
183
183
  "div",
184
- "tvw-bg-cw-container tvw-border-t tvw-border-cw-divider tvw-px-3 tvw-py-2 tvw-ml-4 tvw-mr-3 tvw-mb-1 tvw-rounded-b tvw-overflow-auto tvw-max-h-[300px]"
184
+ "persona-bg-persona-container persona-border-t persona-border-persona-divider persona-px-3 persona-py-2 persona-ml-4 persona-mr-3 persona-mb-1 persona-rounded-b persona-overflow-auto persona-max-h-[300px]"
185
185
  );
186
186
 
187
187
  const payloadContent = createElement(
188
188
  "pre",
189
- "tvw-m-0 tvw-whitespace-pre-wrap tvw-break-all tvw-text-[11px] tvw-text-cw-secondary tvw-font-mono"
189
+ "persona-m-0 persona-whitespace-pre-wrap persona-break-all persona-text-[11px] persona-text-persona-secondary persona-font-mono"
190
190
  );
191
191
  payloadContent.textContent = formattedPayload;
192
192
 
@@ -212,7 +212,7 @@ function renderEventRow(
212
212
  const isExpanded = expandedSet.has(event.id);
213
213
  const wrapper = createElement(
214
214
  "div",
215
- "tvw-border-b tvw-border-cw-divider tvw-text-xs"
215
+ "persona-border-b persona-border-persona-divider persona-text-xs"
216
216
  );
217
217
  applyCustomClasses(wrapper, esConfig.classNames?.eventRow);
218
218
 
@@ -242,14 +242,14 @@ function renderEventRow(
242
242
  // Main row line
243
243
  const row = createElement(
244
244
  "div",
245
- "tvw-flex tvw-items-center tvw-gap-2 tvw-px-3 tvw-py-3 hover:tvw-bg-cw-container tvw-cursor-pointer tvw-group"
245
+ "persona-flex persona-items-center persona-gap-2 persona-px-3 persona-py-3 hover:persona-bg-persona-container persona-cursor-pointer persona-group"
246
246
  );
247
247
  row.setAttribute("data-event-id", event.id);
248
248
 
249
249
  // 1. Chevron (expand/collapse)
250
250
  const chevron = createElement(
251
251
  "span",
252
- "tvw-flex-shrink-0 tvw-text-cw-muted tvw-w-4 tvw-text-center tvw-flex tvw-items-center tvw-justify-center"
252
+ "persona-flex-shrink-0 persona-text-persona-muted persona-w-4 persona-text-center persona-flex persona-items-center persona-justify-center"
253
253
  );
254
254
  const chevronIcon = renderLucideIcon(
255
255
  isExpanded ? "chevron-down" : "chevron-right",
@@ -262,7 +262,7 @@ function renderEventRow(
262
262
  // 2. Timestamp
263
263
  const timestamp = createElement(
264
264
  "span",
265
- "tvw-text-[11px] tvw-text-cw-muted tvw-whitespace-nowrap tvw-flex-shrink-0 tvw-font-mono tvw-w-[70px]"
265
+ "persona-text-[11px] persona-text-persona-muted persona-whitespace-nowrap persona-flex-shrink-0 persona-font-mono persona-w-[70px]"
266
266
  );
267
267
  const tsFormat = esConfig.timestampFormat ?? "relative";
268
268
  timestamp.textContent =
@@ -275,7 +275,7 @@ function renderEventRow(
275
275
  if (esConfig.showSequenceNumbers !== false) {
276
276
  seqNum = createElement(
277
277
  "span",
278
- "tvw-text-[11px] tvw-text-cw-muted tvw-font-mono tvw-flex-shrink-0 tvw-w-[28px] tvw-text-right"
278
+ "persona-text-[11px] persona-text-persona-muted persona-font-mono persona-flex-shrink-0 persona-w-[28px] persona-text-right"
279
279
  );
280
280
  seqNum.textContent = String(index + 1);
281
281
  }
@@ -284,7 +284,7 @@ function renderEventRow(
284
284
  const badgeColor = getBadgeColor(event.type, esConfig.badgeColors);
285
285
  const badge = createElement(
286
286
  "span",
287
- "tvw-inline-flex tvw-items-center tvw-px-2 tvw-py-0.5 tvw-rounded tvw-text-[11px] tvw-font-mono tvw-font-medium tvw-whitespace-nowrap tvw-flex-shrink-0 tvw-border"
287
+ "persona-inline-flex persona-items-center persona-px-2 persona-py-0.5 persona-rounded persona-text-[11px] persona-font-mono persona-font-medium persona-whitespace-nowrap persona-flex-shrink-0 persona-border"
288
288
  );
289
289
  badge.style.backgroundColor = badgeColor.bg;
290
290
  badge.style.color = badgeColor.text;
@@ -299,18 +299,18 @@ function renderEventRow(
299
299
  if (desc) {
300
300
  descEl = createElement(
301
301
  "span",
302
- "tvw-text-[11px] tvw-text-cw-secondary tvw-truncate tvw-min-w-0"
302
+ "persona-text-[11px] persona-text-persona-secondary persona-truncate persona-min-w-0"
303
303
  );
304
304
  descEl.textContent = desc;
305
305
  }
306
306
 
307
307
  // 6. Spacer
308
- const spacer = createElement("div", "tvw-flex-1 tvw-min-w-0");
308
+ const spacer = createElement("div", "persona-flex-1 persona-min-w-0");
309
309
 
310
310
  // 7. Copy button
311
311
  const copyBtn = createElement(
312
312
  "button",
313
- "tvw-text-cw-muted hover:tvw-text-cw-primary tvw-cursor-pointer tvw-flex-shrink-0 tvw-border-none tvw-bg-transparent tvw-p-0"
313
+ "persona-text-persona-muted hover:persona-text-persona-primary persona-cursor-pointer persona-flex-shrink-0 persona-border-none persona-bg-transparent persona-p-0"
314
314
  );
315
315
  const clipIcon = renderLucideIcon(
316
316
  "clipboard",
@@ -426,7 +426,7 @@ export function createEventStreamView(
426
426
  const customClasses = esConfig.classNames;
427
427
  const container = createElement(
428
428
  "div",
429
- "tvw-event-stream-view tvw-flex tvw-flex-col tvw-flex-1 tvw-min-h-0"
429
+ "persona-event-stream-view persona-flex persona-flex-col persona-flex-1 persona-min-h-0"
430
430
  );
431
431
  applyCustomClasses(container, customClasses?.panel);
432
432
 
@@ -468,36 +468,36 @@ export function createEventStreamView(
468
468
  function buildDefaultToolbar(): HTMLElement {
469
469
  const toolbarOuter = createElement(
470
470
  "div",
471
- "tvw-flex tvw-flex-col tvw-flex-shrink-0"
471
+ "persona-flex persona-flex-col persona-flex-shrink-0"
472
472
  );
473
473
 
474
474
  // --- Header bar ---
475
475
  const headerBar = createElement(
476
476
  "div",
477
- "tvw-flex tvw-items-center tvw-gap-2 tvw-px-4 tvw-py-3 tvw-pb-0 tvw-border-cw-divider tvw-bg-cw-surface tvw-overflow-hidden"
477
+ "persona-flex persona-items-center persona-gap-2 persona-px-4 persona-py-3 persona-pb-0 persona-border-persona-divider persona-bg-persona-surface persona-overflow-hidden"
478
478
  );
479
479
  applyCustomClasses(headerBar, customClasses?.headerBar);
480
480
 
481
481
  // Title
482
482
  const title = createElement(
483
483
  "span",
484
- "tvw-text-sm tvw-font-medium tvw-text-cw-primary tvw-whitespace-nowrap"
484
+ "persona-text-sm persona-font-medium persona-text-persona-primary persona-whitespace-nowrap"
485
485
  );
486
486
  title.textContent = "Events";
487
487
 
488
488
  // Count badge
489
489
  countBadge = createElement(
490
490
  "span",
491
- "tvw-text-[11px] tvw-font-mono tvw-bg-cw-container tvw-text-cw-muted tvw-px-2 tvw-py-0.5 tvw-rounded tvw-border tvw-border-cw-border"
491
+ "persona-text-[11px] persona-font-mono persona-bg-persona-container persona-text-persona-muted persona-px-2 persona-py-0.5 persona-rounded persona-border persona-border-persona-border"
492
492
  );
493
493
  countBadge.textContent = "0";
494
494
 
495
- const headerSpacer = createElement("div", "tvw-flex-1");
495
+ const headerSpacer = createElement("div", "persona-flex-1");
496
496
 
497
497
  // Filter dropdown
498
498
  filterSelect = createElement(
499
499
  "select",
500
- "tvw-text-xs tvw-bg-cw-surface tvw-border tvw-border-cw-border tvw-rounded tvw-px-2.5 tvw-py-1 tvw-text-cw-primary tvw-cursor-pointer"
500
+ "persona-text-xs persona-bg-persona-surface persona-border persona-border-persona-border persona-rounded persona-px-2.5 persona-py-1 persona-text-persona-primary persona-cursor-pointer"
501
501
  ) as HTMLSelectElement;
502
502
  const allOption = createElement("option", "") as HTMLOptionElement;
503
503
  allOption.value = "";
@@ -506,7 +506,7 @@ export function createEventStreamView(
506
506
 
507
507
  // Copy All button
508
508
  const iconBtnClass =
509
- "tvw-inline-flex tvw-items-center tvw-gap-1.5 tvw-rounded tvw-text-xs tvw-text-cw-muted hover:tvw-bg-cw-container hover:tvw-text-cw-primary tvw-cursor-pointer tvw-border tvw-border-cw-border tvw-bg-cw-surface tvw-flex-shrink-0 tvw-px-2.5 tvw-py-1";
509
+ "persona-inline-flex persona-items-center persona-gap-1.5 persona-rounded persona-text-xs persona-text-persona-muted hover:persona-bg-persona-container hover:persona-text-persona-primary persona-cursor-pointer persona-border persona-border-persona-border persona-bg-persona-surface persona-flex-shrink-0 persona-px-2.5 persona-py-1";
510
510
 
511
511
  copyAllBtn = createElement(
512
512
  "button",
@@ -523,7 +523,7 @@ export function createEventStreamView(
523
523
  if (copyAllIcon) copyAllBtn.appendChild(copyAllIcon);
524
524
  const copyAllLabel = createElement(
525
525
  "span",
526
- "tvw-text-xs"
526
+ "persona-text-xs"
527
527
  );
528
528
  copyAllLabel.textContent = "Copy All";
529
529
  copyAllBtn.appendChild(copyAllLabel);
@@ -537,7 +537,7 @@ export function createEventStreamView(
537
537
  // --- Search bar ---
538
538
  const searchBar = createElement(
539
539
  "div",
540
- "tvw-relative tvw-px-4 tvw-py-2.5 tvw-border-b tvw-border-cw-divider tvw-bg-cw-surface"
540
+ "persona-relative persona-px-4 persona-py-2.5 persona-border-b persona-border-persona-divider persona-bg-persona-surface"
541
541
  );
542
542
  applyCustomClasses(searchBar, customClasses?.searchBar);
543
543
 
@@ -545,18 +545,18 @@ export function createEventStreamView(
545
545
  const searchIcon = renderLucideIcon(
546
546
  "search",
547
547
  "14px",
548
- "var(--cw-muted, #9ca3af)",
548
+ "var(--persona-muted, #9ca3af)",
549
549
  1.5
550
550
  );
551
551
  const searchIconWrapper = createElement(
552
552
  "span",
553
- "tvw-absolute tvw-left-6 tvw-top-1/2 tvw--translate-y-1/2 tvw-pointer-events-none tvw-flex tvw-items-center"
553
+ "persona-absolute persona-left-6 persona-top-1/2 persona--translate-y-1/2 persona-pointer-events-none persona-flex persona-items-center"
554
554
  );
555
555
  if (searchIcon) searchIconWrapper.appendChild(searchIcon);
556
556
 
557
557
  searchInput = createElement(
558
558
  "input",
559
- "tvw-text-sm tvw-bg-cw-surface tvw-border tvw-border-cw-border tvw-rounded-md tvw-pl-8 tvw-pr-3 tvw-py-1 tvw-w-full tvw-text-cw-primary"
559
+ "persona-text-sm persona-bg-persona-surface persona-border persona-border-persona-border persona-rounded-md persona-pl-8 persona-pr-3 persona-py-1 persona-w-full persona-text-persona-primary"
560
560
  ) as HTMLInputElement;
561
561
  applyCustomClasses(searchInput, customClasses?.searchInput);
562
562
  searchInput.type = "text";
@@ -564,7 +564,7 @@ export function createEventStreamView(
564
564
 
565
565
  searchClearBtn = createElement(
566
566
  "button",
567
- "tvw-absolute tvw-right-5 tvw-top-1/2 tvw--translate-y-1/2 tvw-text-cw-muted hover:tvw-text-cw-primary tvw-cursor-pointer tvw-border-none tvw-bg-transparent tvw-p-0 tvw-leading-none"
567
+ "persona-absolute persona-right-5 persona-top-1/2 persona--translate-y-1/2 persona-text-persona-muted hover:persona-text-persona-primary persona-cursor-pointer persona-border-none persona-bg-transparent persona-p-0 persona-leading-none"
568
568
  ) as HTMLButtonElement;
569
569
  searchClearBtn.type = "button";
570
570
  searchClearBtn.style.display = "none";
@@ -616,7 +616,7 @@ export function createEventStreamView(
616
616
 
617
617
  const truncationBanner = createElement(
618
618
  "div",
619
- "tvw-text-xs tvw-text-cw-muted tvw-text-center tvw-py-0.5 tvw-px-4 tvw-bg-cw-container tvw-border-b tvw-border-cw-divider tvw-italic tvw-flex-shrink-0"
619
+ "persona-text-xs persona-text-persona-muted persona-text-center persona-py-0.5 persona-px-4 persona-bg-persona-container persona-border-b persona-border-persona-divider persona-italic persona-flex-shrink-0"
620
620
  );
621
621
  truncationBanner.style.display = "none";
622
622
 
@@ -626,19 +626,19 @@ export function createEventStreamView(
626
626
 
627
627
  const eventsListWrapper = createElement(
628
628
  "div",
629
- "tvw-flex-1 tvw-min-h-0 tvw-relative"
629
+ "persona-flex-1 persona-min-h-0 persona-relative"
630
630
  );
631
631
 
632
632
  const eventsList = createElement(
633
633
  "div",
634
- "tvw-event-stream-list tvw-overflow-y-auto tvw-min-h-0"
634
+ "persona-event-stream-list persona-overflow-y-auto persona-min-h-0"
635
635
  );
636
636
  eventsList.style.height = "100%";
637
637
 
638
638
  // Scroll-to-bottom indicator
639
639
  const scrollIndicator = createElement(
640
640
  "div",
641
- "tvw-absolute tvw-bottom-3 tvw-left-1/2 tvw-transform tvw--translate-x-1/2 tvw-bg-cw-accent tvw-text-white tvw-text-xs tvw-px-3 tvw-py-1.5 tvw-rounded-full tvw-cursor-pointer tvw-shadow-md tvw-z-10 tvw-flex tvw-items-center tvw-gap-1"
641
+ "persona-absolute persona-bottom-3 persona-left-1/2 persona-transform persona--translate-x-1/2 persona-bg-persona-accent persona-text-white persona-text-xs persona-px-3 persona-py-1.5 persona-rounded-full persona-cursor-pointer persona-shadow-md persona-z-10 persona-flex persona-items-center persona-gap-1"
642
642
  );
643
643
  applyCustomClasses(scrollIndicator, customClasses?.scrollIndicator);
644
644
  scrollIndicator.style.display = "none";
@@ -655,7 +655,7 @@ export function createEventStreamView(
655
655
  // No matching events message
656
656
  const noResultsMsg = createElement(
657
657
  "div",
658
- "tvw-flex tvw-items-center tvw-justify-center tvw-h-full tvw-text-sm tvw-text-cw-muted"
658
+ "persona-flex persona-items-center persona-justify-center persona-h-full persona-text-sm persona-text-persona-muted"
659
659
  );
660
660
  noResultsMsg.style.display = "none";
661
661
 
@@ -983,7 +983,7 @@ export function createEventStreamView(
983
983
  1.5
984
984
  );
985
985
  if (icon) copyAllBtn.appendChild(icon);
986
- const label = createElement("span", "tvw-text-xs");
986
+ const label = createElement("span", "persona-text-xs");
987
987
  label.textContent = "Copy All";
988
988
  copyAllBtn.appendChild(label);
989
989
  setTimeout(() => {
@@ -995,7 +995,7 @@ export function createEventStreamView(
995
995
  1.5
996
996
  );
997
997
  if (original) copyAllBtn.appendChild(original);
998
- const restoreLabel = createElement("span", "tvw-text-xs");
998
+ const restoreLabel = createElement("span", "persona-text-xs");
999
999
  restoreLabel.textContent = "Copy All";
1000
1000
  copyAllBtn.appendChild(restoreLabel);
1001
1001
  copyAllBtn.disabled = false;