@webmcp-auto-ui/sdk 2.5.27 → 2.5.28
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 +1 -1
- package/src/canvas-vanilla.ts +1 -1
- package/src/canvas.ts +1 -1
- package/src/hyperskills.ts +5 -1
- package/src/index.ts +4 -3
- package/src/short-url.ts +33 -0
- package/src/stores/canvas.svelte.ts +14 -2
- package/src/stores/canvas.ts +84 -5
package/package.json
CHANGED
package/src/canvas-vanilla.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Canvas store — Vanilla (framework-agnostic), no Svelte dependency
|
|
2
2
|
export { canvasVanilla } from './stores/canvas.js';
|
|
3
|
-
export type { Widget, WidgetType, Block, BlockType, Mode, LLMId, ChatMsg, McpToolInfo, CanvasSnapshot } from './stores/canvas.js';
|
|
3
|
+
export type { Widget, WidgetType, Block, BlockType, Mode, LLMId, ChatMsg, McpToolInfo, DataServer, CanvasSnapshot } from './stores/canvas.js';
|
package/src/canvas.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Canvas store — Svelte 5 runes (browser-only, must be imported in Svelte components)
|
|
2
2
|
export { canvas } from './stores/canvas.svelte.js';
|
|
3
|
-
export type { Widget, WidgetType, Block, BlockType, Mode, LLMId, ChatMsg, McpToolInfo } from './stores/canvas.svelte.js';
|
|
3
|
+
export type { Widget, WidgetType, Block, BlockType, Mode, LLMId, ChatMsg, McpToolInfo, DataServer } from './stores/canvas.svelte.js';
|
package/src/hyperskills.ts
CHANGED
|
@@ -32,7 +32,10 @@ async function compressGzip(bytes: Uint8Array): Promise<Uint8Array> {
|
|
|
32
32
|
// @ts-ignore — CompressionStream is part of the DOM lib but may be missing in older TS targets
|
|
33
33
|
const cs = new CompressionStream('gzip');
|
|
34
34
|
const writer = cs.writable.getWriter();
|
|
35
|
-
|
|
35
|
+
// Copy into a fresh Uint8Array to guarantee the underlying buffer is a plain
|
|
36
|
+
// ArrayBuffer (not SharedArrayBuffer/ArrayBufferLike) — required by
|
|
37
|
+
// WritableStreamDefaultWriter<BufferSource> under TS 5.x strict lib.
|
|
38
|
+
writer.write(new Uint8Array(bytes));
|
|
36
39
|
writer.close();
|
|
37
40
|
return new Uint8Array(await new Response(cs.readable).arrayBuffer());
|
|
38
41
|
}
|
|
@@ -87,6 +90,7 @@ export function getHsParam(url?: string): string | null {
|
|
|
87
90
|
return null;
|
|
88
91
|
}
|
|
89
92
|
}
|
|
93
|
+
if (typeof window === 'undefined') return null;
|
|
90
94
|
return hs.getHsParam();
|
|
91
95
|
}
|
|
92
96
|
|
package/src/index.ts
CHANGED
|
@@ -44,9 +44,7 @@ import { encode, decode, hash, diff } from './hyperskills.js';
|
|
|
44
44
|
export async function encodeHyperSkill(skill: HyperSkill, sourceUrl?: string): Promise<string> {
|
|
45
45
|
const base = sourceUrl ?? (typeof window !== 'undefined' ? window.location.href.split('?')[0] : 'https://example.com');
|
|
46
46
|
const json = JSON.stringify(skill);
|
|
47
|
-
|
|
48
|
-
const compress = json.length > 6144 ? 'gz' as const : undefined;
|
|
49
|
-
return encode(base, json, compress ? { compress } : {});
|
|
47
|
+
return encode(base, json, { compress: 'gz' });
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
export async function decodeHyperSkill(urlOrParam: string): Promise<HyperSkill> {
|
|
@@ -94,3 +92,6 @@ export type { McpDemoServer } from './mcp-demo-servers.js';
|
|
|
94
92
|
// Recipe runner — markdown-fence parser + JS/TS/SQL/etc executor over MCP
|
|
95
93
|
export { parseBody, runCode, estimateTokens, safeStringify } from './recipes/index.js';
|
|
96
94
|
export type { ParsedSegment, RunResult, RunLog, RunTab, RecipeData } from './recipes/index.js';
|
|
95
|
+
|
|
96
|
+
// Short URL — domain-dependent compact token
|
|
97
|
+
export { buildShortUrl, getShortToken } from './short-url.js';
|
package/src/short-url.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Domain-dependent short URL — compact token served from the skill's own domain.
|
|
2
|
+
// Not a dedicated subdomain: the skill host resolves `?n=<token>` to the full state.
|
|
3
|
+
|
|
4
|
+
import { hash } from './hyperskills.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Build a short URL from a source URL and the content to share.
|
|
8
|
+
* The short token is a prefix of the content hash, resolved server-side.
|
|
9
|
+
*/
|
|
10
|
+
export async function buildShortUrl(sourceUrl: string, content: string): Promise<string> {
|
|
11
|
+
const h = await hash(sourceUrl, content);
|
|
12
|
+
const token = h.slice(0, 10);
|
|
13
|
+
const u = new URL(sourceUrl);
|
|
14
|
+
u.search = '';
|
|
15
|
+
u.searchParams.set('n', token);
|
|
16
|
+
return u.toString();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Read the short token from a URL or param string. Returns null if absent.
|
|
21
|
+
*/
|
|
22
|
+
export function getShortToken(urlOrParam: string): string | null {
|
|
23
|
+
try {
|
|
24
|
+
if (urlOrParam.startsWith('?') || urlOrParam.includes('=')) {
|
|
25
|
+
const sp = new URLSearchParams(urlOrParam.replace(/^\?/, ''));
|
|
26
|
+
return sp.get('n');
|
|
27
|
+
}
|
|
28
|
+
const u = new URL(urlOrParam);
|
|
29
|
+
return u.searchParams.get('n');
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { canvasVanilla } from './canvas.js';
|
|
10
|
-
import type { Widget, WidgetType, Mode, LLMId, ChatMsg, McpToolInfo } from './canvas.js';
|
|
10
|
+
import type { Widget, WidgetType, Mode, LLMId, ChatMsg, McpToolInfo, DataServer } from './canvas.js';
|
|
11
11
|
|
|
12
12
|
// Re-export types (including deprecated aliases)
|
|
13
|
-
export type { Widget, WidgetType, Mode, LLMId, ChatMsg, McpToolInfo };
|
|
13
|
+
export type { Widget, WidgetType, Mode, LLMId, ChatMsg, McpToolInfo, DataServer };
|
|
14
14
|
export type { Block, BlockType, CanvasSnapshot } from './canvas.js';
|
|
15
15
|
|
|
16
16
|
function createCanvas() {
|
|
@@ -29,6 +29,7 @@ function createCanvas() {
|
|
|
29
29
|
let statusColor = $state(canvasVanilla.statusColor);
|
|
30
30
|
let themeOverrides = $state<Record<string, string>>(canvasVanilla.themeOverrides);
|
|
31
31
|
let enabledServerIds = $state<string[]>(canvasVanilla.enabledServerIds);
|
|
32
|
+
let dataServers = $state<DataServer[]>(canvasVanilla.dataServers);
|
|
32
33
|
|
|
33
34
|
// ── Derived ─────────────────────────────────────────────────────────────
|
|
34
35
|
const blockCount = $derived(blocks.length);
|
|
@@ -51,6 +52,7 @@ function createCanvas() {
|
|
|
51
52
|
statusColor = s.statusColor;
|
|
52
53
|
themeOverrides = s.themeOverrides;
|
|
53
54
|
enabledServerIds = canvasVanilla.enabledServerIds;
|
|
55
|
+
dataServers = canvasVanilla.dataServers;
|
|
54
56
|
});
|
|
55
57
|
|
|
56
58
|
// ── Return public API ───────────────────────────────────────────────────
|
|
@@ -112,6 +114,16 @@ function createCanvas() {
|
|
|
112
114
|
get enabledServerIds() { return enabledServerIds; },
|
|
113
115
|
setEnabledServers: canvasVanilla.setEnabledServers.bind(canvasVanilla),
|
|
114
116
|
|
|
117
|
+
// Data servers (multi-MCP) — additive, coexists with mcp* primary fields
|
|
118
|
+
get dataServers() { return dataServers; },
|
|
119
|
+
set dataServers(v: DataServer[]) { canvasVanilla.dataServers = v; },
|
|
120
|
+
addDataServer: canvasVanilla.addDataServer.bind(canvasVanilla),
|
|
121
|
+
removeDataServer: canvasVanilla.removeDataServer.bind(canvasVanilla),
|
|
122
|
+
getDataServer: canvasVanilla.getDataServer.bind(canvasVanilla),
|
|
123
|
+
setDataServerMeta: canvasVanilla.setDataServerMeta.bind(canvasVanilla),
|
|
124
|
+
setDataServerEnabled: canvasVanilla.setDataServerEnabled.bind(canvasVanilla),
|
|
125
|
+
toggleDataServer: canvasVanilla.toggleDataServer.bind(canvasVanilla),
|
|
126
|
+
|
|
115
127
|
// HyperSkill
|
|
116
128
|
buildSkillJSON: canvasVanilla.buildSkillJSON.bind(canvasVanilla),
|
|
117
129
|
buildHyperskillParam: canvasVanilla.buildHyperskillParam.bind(canvasVanilla),
|
package/src/stores/canvas.ts
CHANGED
|
@@ -46,6 +46,17 @@ export interface McpToolInfo {
|
|
|
46
46
|
inputSchema?: Record<string, unknown>;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export interface DataServer {
|
|
50
|
+
name: string; // unique identifier (user-chosen label)
|
|
51
|
+
url: string;
|
|
52
|
+
kind: 'data';
|
|
53
|
+
enabled: boolean; // user intent; bridge only connects to enabled servers
|
|
54
|
+
connected: boolean; // flipped by the bridge after handshake
|
|
55
|
+
tools?: McpToolInfo[];
|
|
56
|
+
recipes?: { name: string; description?: string; body?: string }[];
|
|
57
|
+
error?: string; // handshake error message, if any
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
export interface CanvasSnapshot {
|
|
50
61
|
blocks: Widget[];
|
|
51
62
|
mode: Mode;
|
|
@@ -61,6 +72,7 @@ export interface CanvasSnapshot {
|
|
|
61
72
|
statusColor: string;
|
|
62
73
|
themeOverrides: Record<string, string>;
|
|
63
74
|
enabledServerIds: string[];
|
|
75
|
+
dataServers: DataServer[];
|
|
64
76
|
blockCount: number;
|
|
65
77
|
isEmpty: boolean;
|
|
66
78
|
}
|
|
@@ -96,6 +108,50 @@ function createCanvasVanilla() {
|
|
|
96
108
|
let _statusColor = 'text-zinc-600';
|
|
97
109
|
let _themeOverrides: Record<string, string> = {};
|
|
98
110
|
let _enabledServerIds: string[] = ['autoui'];
|
|
111
|
+
let _dataServers: DataServer[] = [];
|
|
112
|
+
|
|
113
|
+
// ── Data servers (multi-MCP) ───────────────────────────────────────────
|
|
114
|
+
function addDataServer(desc: { name: string; url: string }): DataServer {
|
|
115
|
+
const existing = _dataServers.find((s) => s.name === desc.name);
|
|
116
|
+
if (existing) return existing;
|
|
117
|
+
const srv: DataServer = { name: desc.name, url: desc.url, kind: 'data', enabled: true, connected: false };
|
|
118
|
+
_dataServers = [..._dataServers, srv];
|
|
119
|
+
notify();
|
|
120
|
+
return srv;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function removeDataServer(name: string): boolean {
|
|
124
|
+
const before = _dataServers.length;
|
|
125
|
+
_dataServers = _dataServers.filter((s) => s.name !== name);
|
|
126
|
+
if (_dataServers.length !== before) { notify(); return true; }
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getDataServer(name: string): DataServer | undefined {
|
|
131
|
+
return _dataServers.find((s) => s.name === name);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function setDataServerMeta(name: string, patch: Partial<Omit<DataServer, 'name' | 'url' | 'kind'>>): void {
|
|
135
|
+
const idx = _dataServers.findIndex((s) => s.name === name);
|
|
136
|
+
if (idx < 0) return;
|
|
137
|
+
_dataServers = _dataServers.map((s, i) => i === idx ? { ...s, ...patch } : s);
|
|
138
|
+
notify();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function setDataServerEnabled(name: string, enabled: boolean): boolean {
|
|
142
|
+
const s = _dataServers.find((x) => x.name === name);
|
|
143
|
+
if (!s) return false;
|
|
144
|
+
if (s.enabled === enabled) return true;
|
|
145
|
+
_dataServers = _dataServers.map((x) => x.name === name ? { ...x, enabled } : x);
|
|
146
|
+
notify();
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function toggleDataServer(name: string): boolean {
|
|
151
|
+
const s = _dataServers.find((x) => x.name === name);
|
|
152
|
+
if (!s) return false;
|
|
153
|
+
return setDataServerEnabled(name, !s.enabled);
|
|
154
|
+
}
|
|
99
155
|
|
|
100
156
|
// ── Widget actions ─────────────────────────────────────────────────────
|
|
101
157
|
function addWidget(type: WidgetType, data: Record<string, unknown> = {}): Widget {
|
|
@@ -173,12 +229,16 @@ function createCanvasVanilla() {
|
|
|
173
229
|
tools?: McpToolInfo[]
|
|
174
230
|
) {
|
|
175
231
|
_mcpConnected = connected;
|
|
176
|
-
if (name) _mcpName = name;
|
|
177
|
-
if (tools) _mcpTools = tools;
|
|
178
232
|
if (connected) {
|
|
233
|
+
if (name) _mcpName = name;
|
|
234
|
+
if (tools) _mcpTools = tools;
|
|
179
235
|
_statusText = `● ${name} · ${tools?.length ?? 0} tools`;
|
|
180
236
|
_statusColor = 'text-teal-400';
|
|
181
237
|
} else {
|
|
238
|
+
// Reset stale connection state on disconnect so the UI doesn't keep
|
|
239
|
+
// advertising the previous server name / tool list.
|
|
240
|
+
_mcpName = '';
|
|
241
|
+
_mcpTools = [];
|
|
182
242
|
_statusText = '● no MCP connected';
|
|
183
243
|
_statusColor = 'text-zinc-600';
|
|
184
244
|
}
|
|
@@ -222,8 +282,7 @@ function createCanvasVanilla() {
|
|
|
222
282
|
|
|
223
283
|
async function buildHyperskillParam(): Promise<string> {
|
|
224
284
|
const json = JSON.stringify(buildSkillJSON());
|
|
225
|
-
const
|
|
226
|
-
const url = await encode('https://x.local', json, compress ? { compress } : {});
|
|
285
|
+
const url = await encode('https://x.local', json, { compress: 'gz' });
|
|
227
286
|
return new URL(url).searchParams.get('hs')!;
|
|
228
287
|
}
|
|
229
288
|
|
|
@@ -267,10 +326,19 @@ function createCanvasVanilla() {
|
|
|
267
326
|
async function loadFromUrl(url: string): Promise<boolean> {
|
|
268
327
|
try {
|
|
269
328
|
const { content: raw } = await decode(url);
|
|
270
|
-
const decoded = JSON.parse(raw) as {
|
|
329
|
+
const decoded = JSON.parse(raw) as {
|
|
330
|
+
meta?: Record<string, unknown>;
|
|
331
|
+
content?: { blocks?: { type: WidgetType; data: Record<string, unknown> }[] };
|
|
332
|
+
servers?: string[];
|
|
333
|
+
};
|
|
271
334
|
if (decoded.meta?.mcp) _mcpUrl = decoded.meta.mcp as string;
|
|
272
335
|
if (decoded.meta?.llm) _llm = decoded.meta.llm as LLMId;
|
|
273
336
|
if (decoded.meta?.theme) _themeOverrides = decoded.meta.theme as Record<string, string>;
|
|
337
|
+
// Align with loadFromParam: restore enabledServerIds when `servers` is
|
|
338
|
+
// present. buildSkillJSON emits it at the root, but tolerate it under
|
|
339
|
+
// `meta` as well for forward/back compatibility.
|
|
340
|
+
const servers = (decoded.servers ?? (decoded.meta?.servers as string[] | undefined));
|
|
341
|
+
if (Array.isArray(servers)) _enabledServerIds = servers;
|
|
274
342
|
if (decoded.content?.blocks) _blocks = decoded.content.blocks.map((b) => ({ id: uuid(), type: b.type, data: b.data }));
|
|
275
343
|
notify();
|
|
276
344
|
return true;
|
|
@@ -296,6 +364,7 @@ function createCanvasVanilla() {
|
|
|
296
364
|
statusColor: _statusColor,
|
|
297
365
|
themeOverrides: _themeOverrides,
|
|
298
366
|
enabledServerIds: _enabledServerIds,
|
|
367
|
+
dataServers: _dataServers,
|
|
299
368
|
blockCount: _blocks.length,
|
|
300
369
|
isEmpty: _blocks.length === 0,
|
|
301
370
|
};
|
|
@@ -358,6 +427,16 @@ function createCanvasVanilla() {
|
|
|
358
427
|
get enabledServerIds() { return _enabledServerIds; },
|
|
359
428
|
setEnabledServers,
|
|
360
429
|
|
|
430
|
+
// Data servers (multi-MCP) — additive, coexists with mcp* primary fields
|
|
431
|
+
get dataServers() { return _dataServers; },
|
|
432
|
+
set dataServers(v: DataServer[]) { _dataServers = Array.isArray(v) ? v : []; notify(); },
|
|
433
|
+
addDataServer,
|
|
434
|
+
removeDataServer,
|
|
435
|
+
getDataServer,
|
|
436
|
+
setDataServerMeta,
|
|
437
|
+
setDataServerEnabled,
|
|
438
|
+
toggleDataServer,
|
|
439
|
+
|
|
361
440
|
// HyperSkill
|
|
362
441
|
buildSkillJSON, buildHyperskillParam, loadFromParam, loadFromUrl,
|
|
363
442
|
|