@webmcp-auto-ui/ui 2.5.36 → 2.5.38
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/package.json +3 -1
- package/src/agent/MCPserversList.svelte +44 -32
- package/src/agent/RecipeBrowser.svelte +54 -18
- package/src/agent/RemoteMCPserversDemo.svelte +7 -7
- package/src/agent/ToolBrowser.svelte +34 -5
- package/src/agent/WebMCPserversList.svelte +85 -40
- package/src/base/chat-inline.svelte +81 -9
- package/src/index.ts +1 -0
- package/src/primitives/MarkdownView.svelte +12 -2
- package/src/recipe/RecipeCodeBlock.svelte +10 -2
- package/src/recipe/RecipeRunModal.svelte +245 -0
- package/src/widgets/WidgetRenderer.svelte +8 -5
- package/src/widgets/notebook/executors/sql.ts +9 -6
- package/src/widgets/notebook/import-modal-api.ts +15 -19
- package/src/widgets/notebook/import-modal.svelte +5 -4
- package/src/widgets/notebook/left-pane.ts +23 -3
- package/src/widgets/notebook/notebook.svelte +0 -1
- package/src/widgets/notebook/notebook.ts +437 -80
- package/src/widgets/notebook/resource-extractor.ts +16 -1
- package/src/widgets/notebook/share-handlers.ts +90 -1
- package/src/widgets/notebook/shared.ts +260 -88
- package/src/widgets/rich/cards.svelte +3 -1
- package/src/widgets/rich/chart-rich.svelte +73 -7
- package/src/widgets/rich/data-table.svelte +28 -7
- package/src/widgets/rich/map.svelte +392 -0
- package/src/widgets/rich/stat-card.svelte +119 -20
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Consumed by import-modals.ts and left-pane.ts.
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
|
|
7
|
-
import { parseBody } from '@webmcp-auto-ui/sdk';
|
|
7
|
+
import { parseBody, parseWidgetDisplayCall } from '@webmcp-auto-ui/sdk';
|
|
8
8
|
import { uid, defaultCellContent } from './shared.js';
|
|
9
9
|
import type { NotebookCell, CellType } from './shared.js';
|
|
10
10
|
|
|
@@ -80,6 +80,21 @@ export function extractCellFromFence(lang: string, content: string): NotebookCel
|
|
|
80
80
|
return { id: uid(), type: 'sql', content: sql.trim(), hideSource: false, hideResult: false };
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
+
// widget_display is a local WebMCP tool (autoui), not a remote MCP tool —
|
|
84
|
+
// route it to the JS sandbox `widget()` helper which captures and renders
|
|
85
|
+
// inline. callTool() would fail with "No MCP server exposes tool".
|
|
86
|
+
if (/^(?:[A-Za-z_]\w*_)?widget_display$/.test(name)) {
|
|
87
|
+
const parsed = parseWidgetDisplayCall(trimmed);
|
|
88
|
+
if (parsed) {
|
|
89
|
+
const paramsLiteral = JSON.stringify(parsed.params, null, 2);
|
|
90
|
+
return {
|
|
91
|
+
id: uid(),
|
|
92
|
+
type: 'js',
|
|
93
|
+
content: `return widget('${parsed.name}', ${paramsLiteral})`,
|
|
94
|
+
hideSource: false, hideResult: false,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
83
98
|
return {
|
|
84
99
|
id: uid(),
|
|
85
100
|
type: 'js',
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
import { encode, buildShortUrl } from '@webmcp-auto-ui/sdk';
|
|
8
|
+
import { canvasVanilla } from '@webmcp-auto-ui/sdk/canvas-vanilla';
|
|
8
9
|
import type { NotebookState, NotebookCell } from './shared.js';
|
|
9
10
|
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
@@ -27,8 +28,23 @@ export async function shareAsMarkdown(state: NotebookState): Promise<void> {
|
|
|
27
28
|
triggerDownload(blob, sanitizeFilename(state.title || 'notebook') + '.md');
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Serialize a notebook state as a HyperSkill standalone markdown:
|
|
33
|
+
* ---
|
|
34
|
+
* title: "..."
|
|
35
|
+
* description: "..."
|
|
36
|
+
* servers:
|
|
37
|
+
* - name: foo
|
|
38
|
+
* url: https://...
|
|
39
|
+
* ---
|
|
40
|
+
* <body with ```sql / ```js fenced cells>
|
|
41
|
+
*
|
|
42
|
+
* Re-parsable via @webmcp-auto-ui/core::parseFrontmatter + @webmcp-auto-ui/sdk::parseBody.
|
|
43
|
+
*/
|
|
44
|
+
export function serializeToMarkdown(state: NotebookState): string {
|
|
45
|
+
const fm = buildFrontmatter(state);
|
|
31
46
|
const parts: string[] = [];
|
|
47
|
+
if (fm) parts.push(fm);
|
|
32
48
|
if (state.title) parts.push(`# ${state.title}`, '');
|
|
33
49
|
for (const cell of state.cells) {
|
|
34
50
|
if (cell.type === 'md') {
|
|
@@ -46,6 +62,79 @@ function serializeToMarkdown(state: NotebookState): string {
|
|
|
46
62
|
return parts.join('\n').trim() + '\n';
|
|
47
63
|
}
|
|
48
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Emit YAML frontmatter for HyperSkill format. Reads connected MCP servers from
|
|
67
|
+
* the canvas store. Returns '' when nothing useful to declare (no title, no
|
|
68
|
+
* description, no servers) — caller can skip prepending.
|
|
69
|
+
*/
|
|
70
|
+
function buildFrontmatter(state: NotebookState): string {
|
|
71
|
+
const title = (state.title || '').trim();
|
|
72
|
+
const description = extractDescription(state);
|
|
73
|
+
const servers = collectEnabledServers();
|
|
74
|
+
const webmcpServers = collectEnabledWebmcpServers();
|
|
75
|
+
if (!title && !description && servers.length === 0 && webmcpServers.length === 0) return '';
|
|
76
|
+
|
|
77
|
+
const lines: string[] = ['---'];
|
|
78
|
+
if (title) lines.push(`title: ${yamlQuote(title)}`);
|
|
79
|
+
if (description) lines.push(`description: ${yamlQuote(description)}`);
|
|
80
|
+
if (servers.length > 0) {
|
|
81
|
+
lines.push('servers:');
|
|
82
|
+
for (const s of servers) {
|
|
83
|
+
lines.push(` - name: ${yamlQuote(s.name)}`);
|
|
84
|
+
lines.push(` url: ${yamlQuote(s.url)}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (webmcpServers.length > 0) {
|
|
88
|
+
// YAML flow-style for compactness (registry ids, no spaces).
|
|
89
|
+
lines.push(`webmcp_servers: [${webmcpServers.map(yamlQuote).join(', ')}]`);
|
|
90
|
+
}
|
|
91
|
+
lines.push('---', '');
|
|
92
|
+
return lines.join('\n');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Read canvas.enabledServerIds — the registry ids (e.g. 'autoui', 'd3',
|
|
97
|
+
* 'observable-plot') of bundled WebMCP servers active in this notebook.
|
|
98
|
+
* The viewer re-instantiates them from @webmcp-auto-ui/servers on load.
|
|
99
|
+
*/
|
|
100
|
+
function collectEnabledWebmcpServers(): string[] {
|
|
101
|
+
try {
|
|
102
|
+
const ids = (canvasVanilla as { enabledServerIds?: string[] }).enabledServerIds ?? [];
|
|
103
|
+
return ids.filter((id): id is string => typeof id === 'string' && id.length > 0);
|
|
104
|
+
} catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function extractDescription(state: NotebookState): string {
|
|
110
|
+
for (const cell of state.cells) {
|
|
111
|
+
if (cell.type !== 'md') continue;
|
|
112
|
+
const text = stripHtml(cell.content).trim();
|
|
113
|
+
if (!text) continue;
|
|
114
|
+
// First non-heading line of the first md cell.
|
|
115
|
+
const lines = text.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
116
|
+
const prose = lines.find((l) => !/^#{1,6}\s/.test(l) && !/^[-*]\s/.test(l));
|
|
117
|
+
if (prose) return prose.slice(0, 200);
|
|
118
|
+
}
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function collectEnabledServers(): { name: string; url: string }[] {
|
|
123
|
+
try {
|
|
124
|
+
const servers = canvasVanilla.dataServers ?? [];
|
|
125
|
+
return servers
|
|
126
|
+
.filter((s: any) => s?.enabled && s?.url && s?.name && s.name !== 'autoui' && s.kind !== 'ui' && s.kind !== 'webmcp')
|
|
127
|
+
.map((s: any) => ({ name: String(s.name), url: String(s.url) }));
|
|
128
|
+
} catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Quote a YAML scalar safely. Conservative: always double-quote. */
|
|
134
|
+
function yamlQuote(s: string): string {
|
|
135
|
+
return '"' + s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"';
|
|
136
|
+
}
|
|
137
|
+
|
|
49
138
|
function stripHtml(s: string): string {
|
|
50
139
|
if (typeof document === 'undefined') return s;
|
|
51
140
|
const d = document.createElement('div');
|