@webmcp-auto-ui/sdk 0.1.0 → 0.2.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webmcp-auto-ui/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Skills CRUD, HyperSkill format, Svelte 5 stores",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
"svelte-check": "^4.0.0",
|
|
33
33
|
"typescript": "^5.0.0"
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|
package/src/hyperskill/format.ts
CHANGED
package/src/skills/registry.ts
CHANGED
|
@@ -8,6 +8,10 @@ export interface SkillBlock {
|
|
|
8
8
|
data: Record<string, unknown>;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
export interface ThemeOverrides {
|
|
12
|
+
[key: string]: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
export interface Skill {
|
|
12
16
|
id: string;
|
|
13
17
|
name: string;
|
|
@@ -16,6 +20,7 @@ export interface Skill {
|
|
|
16
20
|
mcpName?: string;
|
|
17
21
|
llm?: string;
|
|
18
22
|
tags?: string[];
|
|
23
|
+
theme?: ThemeOverrides;
|
|
19
24
|
blocks: SkillBlock[];
|
|
20
25
|
createdAt: number;
|
|
21
26
|
updatedAt: number;
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
export type BlockType =
|
|
7
7
|
| 'stat' | 'kv' | 'list' | 'chart' | 'alert' | 'code' | 'text' | 'actions' | 'tags'
|
|
8
8
|
| 'stat-card' | 'data-table' | 'timeline' | 'profile' | 'trombinoscope' | 'json-viewer'
|
|
9
|
-
| 'hemicycle' | 'chart-rich' | 'cards' | 'grid-data' | 'sankey' | 'map' | 'log'
|
|
9
|
+
| 'hemicycle' | 'chart-rich' | 'cards' | 'grid-data' | 'sankey' | 'map' | 'log'
|
|
10
|
+
| 'gallery' | 'carousel' | 'd3';
|
|
10
11
|
|
|
11
12
|
export type Mode = 'auto' | 'drag' | 'chat';
|
|
12
|
-
export type LLMId = 'haiku' | 'sonnet' | 'gemma-e2b';
|
|
13
|
+
export type LLMId = 'haiku' | 'sonnet' | 'gemma-e2b' | 'gemma-e4b';
|
|
13
14
|
|
|
14
15
|
export interface Block {
|
|
15
16
|
id: string;
|
|
@@ -41,7 +42,7 @@ function msgId() {
|
|
|
41
42
|
function createCanvas() {
|
|
42
43
|
// ── State ────────────────────────────────────────────────────────────────
|
|
43
44
|
let blocks = $state<Block[]>([]);
|
|
44
|
-
let mode = $state<Mode>('
|
|
45
|
+
let mode = $state<Mode>('drag');
|
|
45
46
|
let llm = $state<LLMId>('haiku');
|
|
46
47
|
let mcpUrl = $state('');
|
|
47
48
|
let mcpConnected = $state(false);
|
|
@@ -134,13 +135,20 @@ function createCanvas() {
|
|
|
134
135
|
function setMcpError(err: string) {
|
|
135
136
|
mcpConnected = false;
|
|
136
137
|
mcpConnecting = false;
|
|
137
|
-
statusText = `● erreur: ${err
|
|
138
|
+
statusText = `● erreur: ${err}`;
|
|
138
139
|
statusColor = 'text-red-400';
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
// ── Theme ────────────────────────────────────────────────────────────────
|
|
143
|
+
let themeOverrides = $state<Record<string, string>>({});
|
|
144
|
+
|
|
145
|
+
function setThemeOverrides(overrides: Record<string, string>) {
|
|
146
|
+
themeOverrides = overrides;
|
|
147
|
+
}
|
|
148
|
+
|
|
141
149
|
// ── HyperSkill ───────────────────────────────────────────────────────────
|
|
142
150
|
function buildSkillJSON() {
|
|
143
|
-
|
|
151
|
+
const skill: Record<string, unknown> = {
|
|
144
152
|
version: '1.0',
|
|
145
153
|
name: 'skill-' + Date.now(),
|
|
146
154
|
created: new Date().toISOString(),
|
|
@@ -148,22 +156,32 @@ function createCanvas() {
|
|
|
148
156
|
llm,
|
|
149
157
|
blocks: blocks.map((b) => ({ type: b.type, data: b.data })),
|
|
150
158
|
};
|
|
159
|
+
if (Object.keys(themeOverrides).length > 0) skill.theme = themeOverrides;
|
|
160
|
+
return skill;
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
function buildHyperskillParam(): string {
|
|
154
164
|
const json = JSON.stringify(buildSkillJSON());
|
|
155
|
-
|
|
165
|
+
// Use base64url encoding (URL-safe: no +, /, or = padding issues)
|
|
166
|
+
return btoa(unescape(encodeURIComponent(json)))
|
|
167
|
+
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
156
168
|
}
|
|
157
169
|
|
|
158
170
|
function loadFromParam(param: string): boolean {
|
|
159
171
|
try {
|
|
160
|
-
|
|
172
|
+
// Normalize: base64url → base64 standard, and repair spaces→+ (URLSearchParams damage)
|
|
173
|
+
let b64 = param.replace(/ /g, '+').replace(/-/g, '+').replace(/_/g, '/');
|
|
174
|
+
while (b64.length % 4) b64 += '=';
|
|
175
|
+
|
|
176
|
+
const json = decodeURIComponent(escape(atob(b64)));
|
|
161
177
|
const skill = JSON.parse(json) as {
|
|
162
178
|
mcp?: string; llm?: LLMId;
|
|
179
|
+
theme?: Record<string, string>;
|
|
163
180
|
blocks?: { type: BlockType; data: Record<string, unknown> }[];
|
|
164
181
|
};
|
|
165
182
|
if (skill.mcp) mcpUrl = skill.mcp;
|
|
166
183
|
if (skill.llm) llm = skill.llm;
|
|
184
|
+
if (skill.theme) themeOverrides = skill.theme;
|
|
167
185
|
if (skill.blocks) {
|
|
168
186
|
blocks = skill.blocks.map((b) => ({ id: uuid(), type: b.type, data: b.data }));
|
|
169
187
|
}
|
|
@@ -206,6 +224,10 @@ function createCanvas() {
|
|
|
206
224
|
// MCP
|
|
207
225
|
setMcpConnecting, setMcpConnected, setMcpError,
|
|
208
226
|
|
|
227
|
+
// Theme
|
|
228
|
+
get themeOverrides() { return themeOverrides; },
|
|
229
|
+
setThemeOverrides,
|
|
230
|
+
|
|
209
231
|
// HyperSkill
|
|
210
232
|
buildSkillJSON, buildHyperskillParam, loadFromParam,
|
|
211
233
|
};
|