@webskill/sdk 0.0.5 → 0.1.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.
@@ -0,0 +1,539 @@
1
+ //#region ../core/dist/index.d.ts
2
+ //#region src/errors.d.ts
3
+ type WebSkillErrorCode = 'FS_NOT_FOUND' | 'FS_PATH_OUTSIDE_ROOT' | 'SKILL_NOT_FOUND' | 'SKILL_INVALID_METADATA' | 'SKILL_INVALID_NAME' | 'SKILL_DUPLICATE_NAME' | 'SKILL_UNSUPPORTED_SCRIPT' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'NETWORK_BLOCKED' | 'TOOL_UNSUPPORTED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' | 'UI_UNAVAILABLE' | 'LLM_UNAVAILABLE' | 'LLM_REQUEST_FAILED' | 'INSTALL_FAILED' | 'UNINSTALL_FAILED' | 'EXPORT_FAILED' | 'INTEGRITY_FAILED' | 'FS_PERMISSION_DENIED' | 'MCP_ENDPOINT_UNAVAILABLE' | 'MCP_TOOL_NOT_FOUND' | 'CANDIDATE_INVALID' | 'APPROVAL_REQUIRED' | 'SKILL_QUARANTINED' | 'SKILL_DISABLED' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE';
4
+ /**
5
+ * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
6
+ * @stable
7
+ */
8
+ declare class WebSkillError extends Error {
9
+ readonly code: WebSkillErrorCode;
10
+ readonly details?: unknown;
11
+ constructor(code: WebSkillErrorCode, message: string, details?: unknown);
12
+ }
13
+ //#endregion
14
+ //#region src/contracts/jsonSchema.d.ts
15
+ /**
16
+ * 宽松 JSON Schema:覆盖工具 inputSchema 的常见字段,
17
+ * 索引签名允许透传规范内的其他关键字。供 tools 与后续 UI 复用。
18
+ */
19
+ interface JsonSchema {
20
+ type?: string;
21
+ properties?: Record<string, JsonSchema>;
22
+ required?: string[];
23
+ items?: JsonSchema;
24
+ enum?: unknown[];
25
+ description?: string;
26
+ default?: unknown;
27
+ [key: string]: unknown;
28
+ }
29
+ //#endregion
30
+ //#region src/skill/manifest.d.ts
31
+ type SkillInstallSource = {
32
+ type: 'local';
33
+ path: string;
34
+ } | {
35
+ type: 'http';
36
+ url: string;
37
+ } | {
38
+ type: 'archive';
39
+ data: ArrayBuffer;
40
+ } | {
41
+ type: 'git';
42
+ url: string;
43
+ ref?: string;
44
+ commit?: string;
45
+ } | {
46
+ type: 'npm';
47
+ packageName: string;
48
+ version?: string;
49
+ };
50
+ /** @stable */
51
+ interface SkillManifest {
52
+ schemaVersion: 1;
53
+ name: string;
54
+ version?: string;
55
+ source: SkillInstallSource;
56
+ installedAt: string;
57
+ integrity: {
58
+ algorithm: 'sha256';
59
+ digest: string;
60
+ };
61
+ files: Array<{
62
+ path: string;
63
+ size: number;
64
+ sha256: string;
65
+ }>;
66
+ }
67
+ interface SkillsLockfile {
68
+ schemaVersion: 1;
69
+ skills: Record<string, {
70
+ digest: string;
71
+ installedAt: string;
72
+ source: SkillInstallSource;
73
+ }>;
74
+ }
75
+ interface VerifyResult {
76
+ ok: boolean;
77
+ mismatches: string[];
78
+ }
79
+ /** 技能目录内的安装清单文件名(不参与 files 列表与 digest) */
80
+ declare const SKILL_MANIFEST_FILE = "webskill.skill-manifest.json";
81
+ /** managed root 下的锁定文件名(不参与 files 列表与 digest) */
82
+ declare const SKILLS_LOCKFILE = "skills.lock.json";
83
+ type Sha256Fn = (data: Uint8Array | string) => string | Promise<string>;
84
+ /** 整体 digest:逐文件 "<path>:<sha256>\n" 拼接串(文件按 path 排序)的 sha256(hash 由调用方提供,可为 WebCrypto 异步实现) */
85
+ declare function computeDigest(files: Array<{
86
+ path: string;
87
+ sha256: string;
88
+ }>, sha256: Sha256Fn): Promise<string>;
89
+ /** 由逐文件清单构建 manifest(digest 由 computeDigest 计算) */
90
+ declare function buildManifest(input: {
91
+ name: string;
92
+ version?: string;
93
+ source: SkillInstallSource;
94
+ installedAt: string;
95
+ files: SkillManifest['files'];
96
+ sha256: Sha256Fn;
97
+ }): Promise<SkillManifest>;
98
+ /** 按 manifest.files 比对实际 hash(调用方负责计算 actualHashes) */
99
+ declare function verifyManifest(manifest: SkillManifest, actualHashes: Map<string, string>): VerifyResult;
100
+ //#endregion
101
+ //#region src/fs/types.d.ts
102
+ interface FileStat {
103
+ path: string;
104
+ type: 'file' | 'directory';
105
+ size?: number;
106
+ mtimeMs?: number;
107
+ }
108
+ /**
109
+ * 文件系统抽象:core 只依赖此接口,Node/浏览器各自提供实现。
110
+ * 路径一律使用 `/` 分隔的 POSIX 风格。
111
+ */
112
+ interface FileSystemProvider {
113
+ readonly kind: string;
114
+ readText(path: string): Promise<string>;
115
+ writeText(path: string, content: string): Promise<void>;
116
+ readBinary(path: string): Promise<Uint8Array>;
117
+ writeBinary(path: string, content: Uint8Array): Promise<void>;
118
+ exists(path: string): Promise<boolean>;
119
+ stat(path: string): Promise<FileStat>;
120
+ list(path: string): Promise<FileStat[]>;
121
+ mkdir(path: string): Promise<void>;
122
+ remove(path: string, options?: {
123
+ recursive?: boolean;
124
+ }): Promise<void>;
125
+ }
126
+ //#endregion
127
+ //#region src/fs/memoryFs.d.ts
128
+ /** 内存文件系统:路径一律规范化为 `/` 分隔,写入自动创建父目录 */
129
+ declare class MemoryFS implements FileSystemProvider {
130
+ #private;
131
+ readonly kind = "memory";
132
+ constructor();
133
+ readText(path: string): Promise<string>;
134
+ writeText(path: string, content: string): Promise<void>;
135
+ readBinary(path: string): Promise<Uint8Array>;
136
+ writeBinary(path: string, content: Uint8Array): Promise<void>;
137
+ exists(path: string): Promise<boolean>;
138
+ stat(path: string): Promise<FileStat>;
139
+ list(path: string): Promise<FileStat[]>;
140
+ mkdir(path: string): Promise<void>;
141
+ remove(path: string, options?: {
142
+ recursive?: boolean;
143
+ }): Promise<void>;
144
+ }
145
+ //#endregion
146
+ //#region src/fs/pathSecurity.d.ts
147
+ /** 统一分隔符为 `/`,去除 `.` 段与重复分隔符(不解析 `..`) */
148
+ declare function normalizePath(path: string): string;
149
+ /**
150
+ * 将相对路径安全地解析到 root 之内。
151
+ * 拒绝空路径、绝对路径(`/`、`\\`、`C:\` 形式)与任何 `..` 段。
152
+ */
153
+ declare function resolveInsideRoot(root: string, relativePath: string): string;
154
+ //#endregion
155
+ //#region src/skill/types.d.ts
156
+ type SkillSource = 'local' | 'mcp' | 'generated' | 'installed';
157
+ /**
158
+ * SKILL.md frontmatter 元数据;未知字段原样透传
159
+ * @stable
160
+ */
161
+ interface SkillMetadata {
162
+ name: string;
163
+ description: string;
164
+ license?: string;
165
+ version?: string;
166
+ /** 声明式依赖:精确技能名列表(无版本约束);缺依赖/循环依赖 → error 级校验 */
167
+ dependencies?: string[];
168
+ [key: string]: unknown;
169
+ }
170
+ interface SkillLocation {
171
+ skillRoot: string;
172
+ skillMdPath: string;
173
+ source: SkillSource;
174
+ }
175
+ /** @stable */
176
+ interface SkillDocument {
177
+ metadata: SkillMetadata;
178
+ body: string;
179
+ location: SkillLocation;
180
+ }
181
+ /** Catalog 条目:渐进披露第一层,只含元数据摘要与标记位 */
182
+ interface SkillCatalogEntry {
183
+ name: string;
184
+ description: string;
185
+ version?: string;
186
+ license?: string;
187
+ root: string;
188
+ source: SkillSource;
189
+ hasScripts: boolean;
190
+ hasReferences: boolean;
191
+ hasAssets: boolean;
192
+ }
193
+ /** @stable */
194
+ interface SkillCatalog {
195
+ entries: SkillCatalogEntry[];
196
+ }
197
+ //#endregion
198
+ //#region src/skill/parser.d.ts
199
+ declare function parseSkillMarkdown(raw: string): {
200
+ metadata: SkillMetadata;
201
+ body: string;
202
+ };
203
+ //#endregion
204
+ //#region src/skill/naming.d.ts
205
+ declare const SKILL_NAME_MAX_LENGTH = 64;
206
+ /** Agent Skills 官方命名规范:小写字母/数字/连字符,不允许首尾或连续连字符 */
207
+ declare const SKILL_NAME_PATTERN: RegExp;
208
+ declare function isValidSkillName(name: string): boolean;
209
+ //#endregion
210
+ //#region src/skill/rules.d.ts
211
+ interface SkillIssue {
212
+ /** 与 WebSkillErrorCode 对齐 */
213
+ code: string;
214
+ severity: 'info' | 'warning' | 'error';
215
+ message: string;
216
+ path?: string;
217
+ }
218
+ /**
219
+ * 技能合规规则的唯一实现。SkillDiscovery 与 validateSkills 都必须调用本函数,
220
+ * 禁止各自重复实现规则(避免两套规则漂移)。
221
+ */
222
+ declare function checkSkillRules(input: {
223
+ dirName: string;
224
+ hasSkillMd: boolean;
225
+ metadata?: SkillMetadata;
226
+ parseError?: WebSkillError;
227
+ scriptFileNames?: string[];
228
+ existingNames?: Set<string>;
229
+ /** 全库技能名集合(两趟扫描提供);提供时启用 dependencies 存在性校验 */
230
+ knownSkillNames?: Set<string>;
231
+ }): SkillIssue[];
232
+ /**
233
+ * 循环依赖检测(全量邻接表,discovery 两趟扫描第二趟调用)。
234
+ * 每个环只报一次(error 级,阻断进 Catalog);自引用视为长度 1 的环。
235
+ */
236
+ declare function checkDependencyCycles(adjacency: Map<string, string[]>): {
237
+ issues: SkillIssue[];
238
+ /** 处于环上的技能名(调用方将其排除出 Catalog) */
239
+ involved: Set<string>;
240
+ };
241
+ //#endregion
242
+ //#region src/skill/skillPack.d.ts
243
+ /**
244
+ * 技能包集(skill pack)格式与打包逻辑(node/browser 共用单一来源):
245
+ * webskill.skill-pack.json { schemaVersion: 1, skills: [{ name, digest }] }
246
+ * <skill-a>/SKILL.md … webskill.skill-manifest.json
247
+ * <skill-b>/SKILL.md …
248
+ * fflate 环境无关;文件读取经 FileSystemProvider 抽象。
249
+ */
250
+ /** 包级清单文件名(位于 zip 根,不参与各技能 digest) */
251
+ declare const SKILL_PACK_FILE = "webskill.skill-pack.json";
252
+ /** @stable */
253
+ interface SkillPackManifest {
254
+ schemaVersion: 1;
255
+ skills: Array<{
256
+ name: string;
257
+ digest: string;
258
+ }>;
259
+ }
260
+ /**
261
+ * 多技能打包为单一 zip(包级清单 + 各技能目录含自身 manifest)。
262
+ * manifestBuilder 负责确保技能目录内 manifest 文件存在并返回之(digest 入包级清单)。
263
+ * @stable
264
+ */
265
+ declare function exportSkills(fs: FileSystemProvider, input: {
266
+ roots: string[];
267
+ manifestBuilder: (skillRoot: string) => Promise<SkillManifest>;
268
+ }): Promise<Uint8Array>;
269
+ /** 包级清单解析 + 形状校验;损坏 → INSTALL_FAILED(安装侧保证零残留) */
270
+ declare function parseSkillPackManifest(text: string): SkillPackManifest;
271
+ //#endregion
272
+ //#region src/skill/discovery.d.ts
273
+ interface DiscoveryResult {
274
+ entries: SkillCatalogEntry[];
275
+ issues: SkillIssue[];
276
+ }
277
+ declare class SkillDiscovery {
278
+ #private;
279
+ constructor(fs: FileSystemProvider, roots: string[]);
280
+ discover(): Promise<DiscoveryResult>;
281
+ catalog(): Promise<{
282
+ catalog: SkillCatalog;
283
+ issues: SkillIssue[];
284
+ }>;
285
+ /** 按需加载技能完整文档;技能不存在时抛 SKILL_NOT_FOUND */
286
+ loadDocument(skillName: string): Promise<SkillDocument>;
287
+ }
288
+ //#endregion
289
+ //#region src/skill/validator.d.ts
290
+ interface ValidationReport {
291
+ /** 无 error 级 issue 即 true */
292
+ ok: boolean;
293
+ issues: SkillIssue[];
294
+ }
295
+ /**
296
+ * 合规校验。内部直接复用 SkillDiscovery 的扫描逻辑,
297
+ * 规则判定同样落在 checkSkillRules 单一来源上。
298
+ */
299
+ declare function validateSkills(fs: FileSystemProvider, roots: string[]): Promise<ValidationReport>;
300
+ //#endregion
301
+ //#region src/skill/reader.d.ts
302
+ /** 按技能名读取技能根目录内的文件,全部读取强制经过路径安全检查 */
303
+ declare class SkillReader {
304
+ #private;
305
+ constructor(fs: FileSystemProvider, index: Map<string, string>);
306
+ readSkillMarkdown(skillName: string): Promise<string>;
307
+ readSkillFile(skillName: string, relativePath: string): Promise<string>;
308
+ readSkillBinary(skillName: string, relativePath: string): Promise<Uint8Array>;
309
+ }
310
+ //#endregion
311
+ //#region src/skill/catalog.d.ts
312
+ /** 由条目列表构建 Catalog,保证按名称排序 */
313
+ declare function buildCatalog(entries: SkillCatalogEntry[]): SkillCatalog;
314
+ //#endregion
315
+ //#region src/render/types.d.ts
316
+ /** 可插拔的 Catalog 渲染器 */
317
+ interface CatalogRenderer {
318
+ readonly format: string;
319
+ render(catalog: SkillCatalog): string;
320
+ }
321
+ //#endregion
322
+ //#region src/render/jsonRenderer.d.ts
323
+ declare function renderCatalogJson(catalog: SkillCatalog): string;
324
+ declare const jsonRenderer: CatalogRenderer;
325
+ //#endregion
326
+ //#region src/render/xmlRenderer.d.ts
327
+ /** 转义 XML 五个特殊字符:& < > " ' */
328
+ declare function escapeXml(text: string): string;
329
+ declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
330
+ declare const xmlRenderer: CatalogRenderer;
331
+ //#endregion
332
+ //#region ../runtime/dist/types-CgNC-oQu.d.ts
333
+ //#region src/llm/streamTypes.d.ts
334
+ /** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
335
+ type LlmStreamEvent = {
336
+ type: 'text-delta';
337
+ delta: string;
338
+ } | {
339
+ type: 'tool-calls';
340
+ toolCalls: LlmToolCall[];
341
+ } | {
342
+ type: 'done';
343
+ content?: string;
344
+ };
345
+ //#endregion
346
+ //#region src/llm/types.d.ts
347
+ interface LlmMessage {
348
+ role: 'system' | 'user' | 'assistant' | 'tool';
349
+ content: string;
350
+ /** role=tool 时必填 */
351
+ toolCallId?: string;
352
+ /** role=assistant 发起工具调用时携带 */
353
+ toolCalls?: LlmToolCall[];
354
+ }
355
+ interface LlmToolSpec {
356
+ name: string;
357
+ description?: string;
358
+ inputSchema: JsonSchema;
359
+ }
360
+ interface LlmToolCall {
361
+ id: string;
362
+ name: string;
363
+ arguments: Record<string, unknown>;
364
+ }
365
+ interface LlmResponse {
366
+ content?: string;
367
+ toolCalls?: LlmToolCall[];
368
+ raw?: unknown;
369
+ }
370
+ interface LlmCompleteInput {
371
+ model?: string;
372
+ messages: LlmMessage[];
373
+ tools?: LlmToolSpec[];
374
+ temperature?: number;
375
+ signal?: AbortSignal;
376
+ }
377
+ interface LlmClient {
378
+ complete(input: LlmCompleteInput): Promise<LlmResponse>;
379
+ /** 可选流式接口;实现后 AgentLoop 默认走流式(text-delta 增量 + 最终组装) */
380
+ stream?(input: LlmCompleteInput): AsyncIterable<LlmStreamEvent>;
381
+ }
382
+ //#endregion
383
+ //#region src/artifacts/types.d.ts
384
+ interface Artifact {
385
+ id: string;
386
+ runId: string;
387
+ path: string;
388
+ type: 'text' | 'binary';
389
+ mimeType?: string;
390
+ size: number;
391
+ createdAt: string;
392
+ metadata?: Record<string, unknown>;
393
+ }
394
+ interface ArtifactStore {
395
+ createTextArtifact(input: {
396
+ runId: string;
397
+ path: string;
398
+ content: string;
399
+ mimeType?: string;
400
+ metadata?: Record<string, unknown>;
401
+ }): Promise<Artifact>;
402
+ createBinaryArtifact(input: {
403
+ runId: string;
404
+ path: string;
405
+ content: Uint8Array;
406
+ mimeType?: string;
407
+ metadata?: Record<string, unknown>;
408
+ }): Promise<Artifact>;
409
+ listArtifacts(runId: string): Promise<Artifact[]>;
410
+ }
411
+ //#endregion
412
+ //#region src/interaction/types.d.ts
413
+ type InteractionRequest = {
414
+ type: 'ask';
415
+ id: string;
416
+ message: string;
417
+ schema?: JsonSchema;
418
+ } | {
419
+ type: 'confirm';
420
+ id: string;
421
+ message: string;
422
+ defaultValue?: boolean;
423
+ } | {
424
+ type: 'form';
425
+ id: string;
426
+ title?: string;
427
+ fields: FormField[];
428
+ } | {
429
+ type: 'select';
430
+ id: string;
431
+ message: string;
432
+ options: Array<{
433
+ label: string;
434
+ value: unknown;
435
+ }>;
436
+ } | {
437
+ /**
438
+ * 能力强制授权(require-approval):与脚本自发 confirm 区分,UI 渲染为授权样式
439
+ * @experimental
440
+ */
441
+ type: 'authorize';
442
+ id: string;
443
+ capability: 'readReference' | 'writeArtifact' | 'confirm';
444
+ message: string;
445
+ details?: unknown;
446
+ };
447
+ interface InteractionResponse {
448
+ id: string;
449
+ value?: unknown;
450
+ cancelled?: boolean;
451
+ }
452
+ /** 图表规格($chart 约定的校验后形态;渲染单一来源在 ui/chart/miniChart) */
453
+ interface ChartSpec {
454
+ kind: 'bar' | 'line' | 'pie';
455
+ title?: string;
456
+ labels: string[];
457
+ series: Array<{
458
+ name?: string;
459
+ data: number[];
460
+ }>;
461
+ }
462
+ type RenderBlock = {
463
+ type: 'markdown';
464
+ text: string;
465
+ } | {
466
+ type: 'json';
467
+ data: unknown;
468
+ } | {
469
+ type: 'table';
470
+ columns: string[];
471
+ rows: unknown[][];
472
+ } | {
473
+ type: 'image';
474
+ url: string;
475
+ alt?: string;
476
+ } | {
477
+ type: 'file';
478
+ path: string;
479
+ mimeType?: string;
480
+ size?: number;
481
+ } | {
482
+ type: 'chart';
483
+ chart: ChartSpec;
484
+ };
485
+ interface RenderResultRequest {
486
+ runId: string;
487
+ title?: string;
488
+ summary?: string;
489
+ blocks: RenderBlock[];
490
+ artifacts?: Artifact[];
491
+ }
492
+ /** @stable */
493
+ interface UiBridge {
494
+ request(input: InteractionRequest): Promise<InteractionResponse>;
495
+ progress?(input: {
496
+ runId: string;
497
+ message: string;
498
+ value?: number;
499
+ }): Promise<void>;
500
+ /** 定义即可,阶段 7 消费 */
501
+ renderResult?(input: RenderResultRequest): Promise<void>;
502
+ /** 流式文本增量(流式 LLM 路径下由 AgentLoop 转发) */
503
+ onTextDelta?(runId: string, delta: string): Promise<void> | void;
504
+ }
505
+ interface FormField {
506
+ name: string;
507
+ label: string;
508
+ type: 'text' | 'number' | 'boolean' | 'select' | 'textarea';
509
+ required?: boolean;
510
+ description?: string;
511
+ defaultValue?: unknown;
512
+ options?: Array<{
513
+ label: string;
514
+ value: unknown;
515
+ }>;
516
+ }
517
+ interface InteractionPolicy {
518
+ /** 缺必填参数策略:默认 'user'(表单问用户),'llm' 回喂自愈 */
519
+ missingParams?: 'user' | 'llm';
520
+ /** context.confirm 策略:默认 'required'(真实询问) */
521
+ confirmations?: 'required' | 'auto-approve';
522
+ /** 交互超时,默认 300_000ms */
523
+ interactionTimeoutMs?: number;
524
+ }
525
+ //#endregion
526
+ //#region src/memory/types.d.ts
527
+ /** scope/key 两级记忆存储;scope 约定:session:{id} / skill:{name} / user:{id} */
528
+ interface MemoryStore {
529
+ get(scope: string, key: string): Promise<unknown>;
530
+ set(scope: string, key: string, value: unknown): Promise<void>;
531
+ delete(scope: string, key: string): Promise<void>;
532
+ list(scope: string): Promise<Array<{
533
+ key: string;
534
+ value: unknown;
535
+ }>>;
536
+ clear(scope?: string): Promise<void>;
537
+ }
538
+ //#endregion
539
+ export { exportSkills as $, SkillCatalog as A, SkillReader as B, JsonSchema as C, SKILL_NAME_MAX_LENGTH as D, SKILL_MANIFEST_FILE as E, SkillIssue as F, WebSkillError as G, SkillsLockfile as H, SkillLocation as I, buildManifest as J, WebSkillErrorCode as K, SkillManifest as L, SkillDiscovery as M, SkillDocument as N, SKILL_NAME_PATTERN as O, SkillInstallSource as P, escapeXml as Q, SkillMetadata as R, FileSystemProvider as S, SKILLS_LOCKFILE as T, ValidationReport as U, SkillSource as V, VerifyResult as W, checkSkillRules as X, checkDependencyCycles as Y, computeDigest as Z, RenderResultRequest as _, InteractionPolicy as a, renderAvailableSkillsXml as at, DiscoveryResult as b, LlmClient as c, validateSkills as ct, LlmResponse as d, isValidSkillName as et, LlmStreamEvent as f, RenderBlock as g, MemoryStore as h, FormField as i, parseSkillPackManifest as it, SkillCatalogEntry as j, SKILL_PACK_FILE as k, LlmCompleteInput as l, verifyManifest as lt, LlmToolSpec as m, ArtifactStore as n, normalizePath as nt, InteractionRequest as o, renderCatalogJson as ot, LlmToolCall as p, buildCatalog as q, ChartSpec as r, parseSkillMarkdown as rt, InteractionResponse as s, resolveInsideRoot as st, Artifact as t, jsonRenderer as tt, LlmMessage as u, xmlRenderer as ut, UiBridge as v, MemoryFS as w, FileStat as x, CatalogRenderer as y, SkillPackManifest as z };
@@ -1,4 +1,4 @@
1
- import { A as InteractionResponse, it as RenderResultRequest, k as InteractionRequest, wt as UiBridge } from "./index-BQDc-U1x.js";
1
+ import { _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-CgNC-oQu-DCklnS0h.js";
2
2
  //#region ../ui-react/dist/index.d.ts
3
3
  //#region src/bridgeState.d.ts
4
4
  /**
@@ -26,7 +26,7 @@ declare function InteractionForm({ bridge }: {
26
26
  }): import("react").JSX.Element | null;
27
27
  //#endregion
28
28
  //#region src/components/ResultBlocks.d.ts
29
- /** 订阅 bridge.latestResult 渲染五种 RenderBlock */
29
+ /** 订阅 bridge.latestResult 渲染六种 RenderBlock */
30
30
  declare function ResultBlocks({ bridge }: {
31
31
  bridge: ReactBridgeState;
32
32
  }): import("react").JSX.Element | null;
package/dist/ui-react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as interactionToFormModel, f as collectValues, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-BM-VcQ90.js";
1
+ import { S as renderMiniMarkdown, m as collectValues, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-Dv4a1Jkm.js";
2
2
  import { useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
 
@@ -185,8 +185,18 @@ function MarkdownBlock({ text }) {
185
185
  }, [text]);
186
186
  return /* @__PURE__ */ jsx("div", { ref });
187
187
  }
188
+ function ChartBlock({ chart }) {
189
+ const ref = useRef(null);
190
+ useLayoutEffect(() => {
191
+ const el = ref.current;
192
+ if (!el) return;
193
+ el.replaceChildren(renderMiniChart(chart, el.ownerDocument));
194
+ }, [chart]);
195
+ return /* @__PURE__ */ jsx("div", { ref });
196
+ }
188
197
  function Block({ block }) {
189
198
  switch (block.type) {
199
+ case "chart": return /* @__PURE__ */ jsx(ChartBlock, { chart: block.chart });
190
200
  case "markdown": return /* @__PURE__ */ jsx(MarkdownBlock, { text: block.text });
191
201
  case "json": return /* @__PURE__ */ jsx("pre", {
192
202
  className: "webskill-result__json",
@@ -206,7 +216,7 @@ function Block({ block }) {
206
216
  }
207
217
  }
208
218
  }
209
- /** 订阅 bridge.latestResult 渲染五种 RenderBlock */
219
+ /** 订阅 bridge.latestResult 渲染六种 RenderBlock */
210
220
  function ResultBlocks({ bridge }) {
211
221
  const result = useSyncExternalStore(bridge.subscribe, () => bridge.latestResult);
212
222
  if (!result) return null;
package/dist/ui-vue.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as InteractionResponse, it as RenderResultRequest, k as InteractionRequest, wt as UiBridge } from "./index-BQDc-U1x.js";
1
+ import { _ as RenderResultRequest, o as InteractionRequest, s as InteractionResponse, v as UiBridge } from "./types-CgNC-oQu-DCklnS0h.js";
2
2
  import { PropType } from "vue";
3
3
  //#region ../ui-vue/dist/index.d.ts
4
4
  //#region src/bridgeState.d.ts
@@ -38,7 +38,7 @@ declare const InteractionForm: import("vue").DefineComponent<import("vue").Extra
38
38
  }>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
39
39
  //#endregion
40
40
  //#region src/components/resultBlocks.d.ts
41
- /** 订阅 bridge.state.latestResult 渲染五种 RenderBlock */
41
+ /** 订阅 bridge.state.latestResult 渲染六种 RenderBlock */
42
42
  declare const ResultBlocks: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
43
43
  bridge: {
44
44
  type: PropType<VueBridgeState>;
package/dist/ui-vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as interactionToFormModel, f as collectValues, x as shapeInteractionValue, y as renderMiniMarkdown } from "./dist-BM-VcQ90.js";
1
+ import { S as renderMiniMarkdown, m as collectValues, w as shapeInteractionValue, x as renderMiniChart, y as interactionToFormModel } from "./dist-Dv4a1Jkm.js";
2
2
  import { defineComponent, h, reactive, ref } from "vue";
3
3
 
4
4
  //#region ../ui-vue/dist/index.js
@@ -132,6 +132,13 @@ const InteractionForm = defineComponent({
132
132
  });
133
133
  function renderBlock(block, key) {
134
134
  switch (block.type) {
135
+ case "chart": return h("div", {
136
+ key,
137
+ onVnodeMounted: (vnode) => {
138
+ const el = vnode.el;
139
+ if (el) el.replaceChildren(renderMiniChart(block.chart, el.ownerDocument));
140
+ }
141
+ });
135
142
  case "markdown": return h("div", {
136
143
  key,
137
144
  onVnodeMounted: (vnode) => {
@@ -158,7 +165,7 @@ function renderBlock(block, key) {
158
165
  }
159
166
  }
160
167
  }
161
- /** 订阅 bridge.state.latestResult 渲染五种 RenderBlock */
168
+ /** 订阅 bridge.state.latestResult 渲染六种 RenderBlock */
162
169
  const ResultBlocks = defineComponent({
163
170
  name: "WebSkillResultBlocks",
164
171
  props: { bridge: {