@webmcp-auto-ui/ui 2.5.32 → 2.5.34

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 (81) hide show
  1. package/package.json +16 -2
  2. package/src/agent/DiagnosticModal.svelte +126 -50
  3. package/src/agent/EphemeralBubble.svelte +13 -3
  4. package/src/agent/MCPserversList.svelte +147 -0
  5. package/src/agent/McpConnector.svelte +10 -1
  6. package/src/agent/RecipeBrowser.svelte +384 -0
  7. package/src/agent/RemoteMCPserversDemo.svelte +5 -121
  8. package/src/agent/ToolBrowser.svelte +133 -0
  9. package/src/agent/WebMCPserversList.svelte +2 -0
  10. package/src/agent/useAgentLoop.svelte.ts +396 -0
  11. package/src/base/chat-inline.svelte +68 -0
  12. package/src/base/dialog-content.svelte +3 -1
  13. package/src/base/dialog-trigger.svelte +3 -2
  14. package/src/components/HeaderControls.svelte +78 -0
  15. package/src/index.ts +13 -35
  16. package/src/stores/canvas.svelte.ts +0 -6
  17. package/src/widgets/SafeImage.svelte +67 -0
  18. package/src/widgets/WidgetRenderer.svelte +153 -78
  19. package/src/widgets/notebook/executors/index.ts +0 -1
  20. package/src/widgets/notebook/executors/sql.ts +32 -182
  21. package/src/widgets/notebook/import-modal-api.ts +237 -0
  22. package/src/widgets/notebook/import-modal.svelte +738 -0
  23. package/src/widgets/notebook/left-pane.ts +1 -1
  24. package/src/widgets/notebook/notebook.svelte +75 -0
  25. package/src/widgets/notebook/notebook.ts +38 -73
  26. package/src/widgets/notebook/prose.ts +6 -3
  27. package/src/widgets/notebook/shared.ts +68 -49
  28. package/src/widgets/rich/cards.svelte +74 -0
  29. package/src/widgets/rich/carousel.svelte +126 -0
  30. package/src/widgets/rich/chart-rich.svelte +221 -0
  31. package/src/widgets/rich/chat-input.svelte +51 -0
  32. package/src/widgets/rich/data-table.svelte +132 -0
  33. package/src/widgets/rich/gallery.svelte +115 -0
  34. package/src/widgets/rich/grid-data.svelte +85 -0
  35. package/src/widgets/rich/hemicycle.svelte +95 -0
  36. package/src/widgets/rich/js-sandbox.svelte +67 -0
  37. package/src/widgets/rich/json-viewer.svelte +82 -0
  38. package/src/widgets/rich/log.svelte +62 -0
  39. package/src/widgets/rich/profile.svelte +91 -0
  40. package/src/widgets/rich/sankey.svelte +73 -0
  41. package/src/widgets/rich/stat-card.svelte +60 -0
  42. package/src/widgets/rich/timeline.svelte +95 -0
  43. package/src/widgets/rich/trombinoscope.svelte +87 -0
  44. package/src/widgets/simple/actions.svelte +36 -0
  45. package/src/widgets/simple/alert.svelte +52 -0
  46. package/src/widgets/simple/chart.svelte +38 -0
  47. package/src/widgets/simple/code.svelte +30 -0
  48. package/src/widgets/simple/kv.svelte +31 -0
  49. package/src/widgets/simple/list.svelte +35 -0
  50. package/src/widgets/simple/stat.svelte +36 -0
  51. package/src/widgets/simple/tags.svelte +34 -0
  52. package/src/widgets/simple/text.svelte +130 -0
  53. package/src/widgets/helpers/safe-image.ts +0 -78
  54. package/src/widgets/notebook/import-modals.ts +0 -560
  55. package/src/widgets/notebook/recipe-browser.ts +0 -350
  56. package/src/widgets/rich/cards.ts +0 -181
  57. package/src/widgets/rich/carousel.ts +0 -319
  58. package/src/widgets/rich/chart-rich.ts +0 -386
  59. package/src/widgets/rich/d3.ts +0 -503
  60. package/src/widgets/rich/data-table.ts +0 -342
  61. package/src/widgets/rich/gallery.ts +0 -350
  62. package/src/widgets/rich/grid-data.ts +0 -173
  63. package/src/widgets/rich/hemicycle.ts +0 -313
  64. package/src/widgets/rich/js-sandbox.ts +0 -122
  65. package/src/widgets/rich/json-viewer.ts +0 -202
  66. package/src/widgets/rich/log.ts +0 -143
  67. package/src/widgets/rich/map.ts +0 -218
  68. package/src/widgets/rich/profile.ts +0 -256
  69. package/src/widgets/rich/sankey.ts +0 -257
  70. package/src/widgets/rich/stat-card.ts +0 -125
  71. package/src/widgets/rich/timeline.ts +0 -179
  72. package/src/widgets/rich/trombinoscope.ts +0 -246
  73. package/src/widgets/simple/actions.ts +0 -89
  74. package/src/widgets/simple/alert.ts +0 -100
  75. package/src/widgets/simple/chart.ts +0 -189
  76. package/src/widgets/simple/code.ts +0 -79
  77. package/src/widgets/simple/kv.ts +0 -68
  78. package/src/widgets/simple/list.ts +0 -89
  79. package/src/widgets/simple/stat.ts +0 -58
  80. package/src/widgets/simple/tags.ts +0 -125
  81. package/src/widgets/simple/text.ts +0 -198
@@ -1,198 +0,0 @@
1
- /**
2
- * Vanilla renderer for the "text" / TextBlock widget.
3
- *
4
- * Mirrors the Svelte TextBlock.svelte output: a <div class="tb-md ..."> whose
5
- * innerHTML is produced by a minimal, XSS-safe markdown -> HTML function.
6
- *
7
- * XSS note: renderMarkdown() escapes &, <, >, " BEFORE applying inline rules,
8
- * so user-controlled text can only reach the DOM as already-escaped entities or
9
- * as the structural tags we explicitly emit (h1-6, p, strong, em, code, pre, ul,
10
- * ol, li, a, hr). Using innerHTML here is therefore safe — the function is the
11
- * single source of trust for sanitization.
12
- */
13
-
14
- export interface TextBlockData {
15
- content?: string;
16
- }
17
-
18
- /** Minimal markdown → HTML renderer (no deps, naturally XSS-safe: only produces known tags) */
19
- function renderMarkdown(src: string): string {
20
- if (!src) return '';
21
-
22
- // Escape HTML entities first (XSS protection)
23
- const esc = (s: string) =>
24
- s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
25
-
26
- const lines = src.split('\n');
27
- const out: string[] = [];
28
- let inCode = false;
29
- let codeLines: string[] = [];
30
- let inUl = false;
31
- let inOl = false;
32
-
33
- const closeList = () => {
34
- if (inUl) { out.push('</ul>'); inUl = false; }
35
- if (inOl) { out.push('</ol>'); inOl = false; }
36
- };
37
-
38
- /** Inline formatting: bold, italic, code, links */
39
- const inline = (s: string): string => {
40
- return esc(s)
41
- .replace(/`([^`]+)`/g, '<code>$1</code>')
42
- .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
43
- .replace(/\*([^*]+)\*/g, '<em>$1</em>')
44
- // Whitelist URL protocols to block javascript:/data:/vbscript: XSS via markdown links.
45
- .replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, label, href) =>
46
- /^(https?:|\/|#|mailto:)/i.test(href)
47
- ? `<a href="${href}" target="_blank" rel="noopener">${label}</a>`
48
- : label,
49
- );
50
- };
51
-
52
- for (const line of lines) {
53
- // Fenced code block toggle
54
- if (line.trimStart().startsWith('```')) {
55
- if (!inCode) {
56
- closeList();
57
- inCode = true;
58
- codeLines = [];
59
- } else {
60
- out.push(`<pre><code>${esc(codeLines.join('\n'))}</code></pre>`);
61
- inCode = false;
62
- }
63
- continue;
64
- }
65
- if (inCode) { codeLines.push(line); continue; }
66
-
67
- const trimmed = line.trim();
68
-
69
- // Empty line → close lists, push break
70
- if (!trimmed) { closeList(); out.push(''); continue; }
71
-
72
- // Headers
73
- const hMatch = trimmed.match(/^(#{1,6})\s+(.+)$/);
74
- if (hMatch) {
75
- closeList();
76
- const level = hMatch[1].length;
77
- out.push(`<h${level}>${inline(hMatch[2])}</h${level}>`);
78
- continue;
79
- }
80
-
81
- // Unordered list
82
- if (/^[-*+]\s+/.test(trimmed)) {
83
- if (inOl) { out.push('</ol>'); inOl = false; }
84
- if (!inUl) { out.push('<ul>'); inUl = true; }
85
- out.push(`<li>${inline(trimmed.replace(/^[-*+]\s+/, ''))}</li>`);
86
- continue;
87
- }
88
-
89
- // Ordered list
90
- const olMatch = trimmed.match(/^(\d+)\.\s+(.+)$/);
91
- if (olMatch) {
92
- if (inUl) { out.push('</ul>'); inUl = false; }
93
- if (!inOl) { out.push('<ol>'); inOl = true; }
94
- out.push(`<li>${inline(olMatch[2])}</li>`);
95
- continue;
96
- }
97
-
98
- // Horizontal rule
99
- if (/^[-*_]{3,}$/.test(trimmed)) {
100
- closeList();
101
- out.push('<hr>');
102
- continue;
103
- }
104
-
105
- // Regular paragraph line
106
- closeList();
107
- out.push(`<p>${inline(trimmed)}</p>`);
108
- }
109
-
110
- // Close any open blocks
111
- if (inCode) out.push(`<pre><code>${esc(codeLines.join('\n'))}</code></pre>`);
112
- closeList();
113
-
114
- return out.join('\n');
115
- }
116
-
117
- /** Scoped styles — emitted once per document, matching TextBlock.svelte :global rules. */
118
- const STYLE_ID = 'autoui-text-widget-styles';
119
- const STYLE_CSS = `
120
- .tb-md { color: var(--color-text2); }
121
- .tb-md h1 { font-size: 1.5em; font-weight: 700; color: var(--color-text1); margin: 0.8em 0 0.4em; }
122
- .tb-md h2 { font-size: 1.25em; font-weight: 600; color: var(--color-text1); margin: 0.7em 0 0.35em; }
123
- .tb-md h3 { font-size: 1.1em; font-weight: 600; color: var(--color-text1); margin: 0.6em 0 0.3em; }
124
- .tb-md h4, .tb-md h5, .tb-md h6 { font-size: 1em; font-weight: 600; color: var(--color-text1); margin: 0.5em 0 0.25em; }
125
- .tb-md p { margin: 0.4em 0; }
126
- .tb-md strong { font-weight: 600; color: var(--color-text1); }
127
- .tb-md em { font-style: italic; }
128
- .tb-md a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
129
- .tb-md a:hover { opacity: 0.8; }
130
- .tb-md ul, .tb-md ol { margin: 0.4em 0; padding-left: 1.5em; }
131
- .tb-md ul { list-style: disc; }
132
- .tb-md ol { list-style: decimal; }
133
- .tb-md li { margin: 0.15em 0; }
134
- .tb-md code { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 0.9em; background: var(--color-surface2); padding: 0.15em 0.35em; border-radius: 4px; }
135
- .tb-md pre { background: var(--color-surface2); border-radius: 6px; padding: 0.75em 1em; margin: 0.5em 0; overflow-x: auto; }
136
- .tb-md pre code { background: none; padding: 0; font-size: 0.85em; }
137
- .tb-md hr { border: none; border-top: 1px solid var(--color-surface2); margin: 0.8em 0; }
138
- `;
139
-
140
- function ensureStyles(doc: Document): void {
141
- if (doc.getElementById(STYLE_ID)) return;
142
- const style = doc.createElement('style');
143
- style.id = STYLE_ID;
144
- style.textContent = STYLE_CSS;
145
- doc.head.appendChild(style);
146
- }
147
-
148
- /**
149
- * Mount a text / markdown widget into `container`.
150
- *
151
- * Returns an `unmount()` function that clears the container and removes any
152
- * attached listeners.
153
- */
154
- export function render(container: HTMLElement, data: any): () => void {
155
- const payload = (data ?? {}) as Partial<TextBlockData>;
156
- const content = typeof payload.content === 'string' ? payload.content : '';
157
-
158
- ensureStyles(container.ownerDocument ?? document);
159
-
160
- const root = container.ownerDocument.createElement('div');
161
- root.className = 'tb-md p-4 md:p-5 text-sm leading-relaxed';
162
-
163
- if (!content.trim()) {
164
- // Empty-state placeholder — keeps layout, signals absence to a11y tree.
165
- const placeholder = container.ownerDocument.createElement('p');
166
- placeholder.textContent = '';
167
- placeholder.setAttribute('aria-label', 'empty text block');
168
- placeholder.style.opacity = '0.5';
169
- placeholder.style.fontStyle = 'italic';
170
- root.appendChild(placeholder);
171
- } else {
172
- // Safe: renderMarkdown() escapes user text before emitting tags.
173
- root.innerHTML = renderMarkdown(content);
174
- }
175
-
176
- // Delegated click handler — lets links emit widget:interact for host apps
177
- // (e.g. analytics / canvas telemetry) without blocking default navigation.
178
- const onClick = (ev: MouseEvent) => {
179
- const target = ev.target as HTMLElement | null;
180
- if (!target) return;
181
- const anchor = target.closest('a');
182
- if (!anchor || !root.contains(anchor)) return;
183
- container.dispatchEvent(
184
- new CustomEvent('widget:interact', {
185
- detail: { action: 'link', payload: { href: (anchor as HTMLAnchorElement).href } },
186
- bubbles: true,
187
- }),
188
- );
189
- };
190
- root.addEventListener('click', onClick);
191
-
192
- container.appendChild(root);
193
-
194
- return () => {
195
- root.removeEventListener('click', onClick);
196
- container.innerHTML = '';
197
- };
198
- }