@webskill/sdk 0.2.8 → 0.4.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.
Files changed (38) hide show
  1. package/README.md +42 -0
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +4 -9
  4. package/dist/{catalogComponents-C_V39rbF-BOHveMWa.js → catalogComponents-KsujmL4b-Clx1kCnU.js} +278 -122
  5. package/dist/client-BCM6Z3yq-qUQNkKrK.js +7787 -0
  6. package/dist/{dist-BQzncxXg.js → dist-8oQRa8Xz.js} +212 -13
  7. package/dist/{dist-B9VLwOME.js → dist-C-Sh0MDU.js} +1019 -317
  8. package/dist/{dist-CtBLBbEz.js → dist-D9Lcn5Pp.js} +528 -838
  9. package/dist/governance.d.ts +46 -11
  10. package/dist/governance.js +152 -25
  11. package/dist/{index-7DVaZJU7.d.ts → index-CHXxDccV.d.ts} +62 -144
  12. package/dist/{index-QrHtAudz.d.ts → index-DLfR2Y6I.d.ts} +412 -21
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.js +4 -3
  15. package/dist/mcp.d.ts +2 -2
  16. package/dist/mcp.js +2 -2
  17. package/dist/memoryArtifactStore-BtOeB_hm-tj3fC5ip.js +78 -0
  18. package/dist/node.d.ts +297 -4
  19. package/dist/node.js +281 -7
  20. package/dist/{openUiLibrary-B8-Cvou9-D3RsU2EB.js → openUiLibrary-YLS-cxyT-C96jWDQq.js} +6 -5
  21. package/dist/skillVersionStore-uyefLPR1-DXOzbksv.d.ts +158 -0
  22. package/dist/stdio-CFMoANJJ-BxrTeXh7.js +31 -0
  23. package/dist/{testing-BUoXvm1u.js → testing-DDCJWvgA.js} +8 -6
  24. package/dist/testing.d.ts +1 -1
  25. package/dist/testing.js +2 -2
  26. package/dist/{types-AmKCKJn_-BogJPQHU.d.ts → types-7Wcg--Vh-1YlQ4jF9.d.ts} +219 -70
  27. package/dist/types-WovEf4ED-CZSDiiBU.js +6215 -0
  28. package/dist/ui-react.d.ts +329 -18
  29. package/dist/ui-react.js +3715 -3464
  30. package/dist/ui-vue.d.ts +1 -1
  31. package/dist/ui-vue.js +1 -1
  32. package/dist/ui.d.ts +4 -3
  33. package/dist/ui.js +3 -3
  34. package/dist/{webskillLitCatalog-CNaUpasU-CfSRvqCZ.js → webskillLitCatalog-CSTbhBe_-CYIs5BX8.js} +312 -122
  35. package/package.json +4 -7
  36. package/dist/jsonRenderRegistry-9GrWP_hE-CQY8bT9w.js +0 -2468
  37. package/dist/memoryArtifactStore-C9lFVqPF-yFz6yJj0.js +0 -48
  38. package/dist/skillVersionStore-B7rGjtMi-BgnQho9v.d.ts +0 -365
@@ -1,6 +1,6 @@
1
1
  //#region ../core/dist/index.d.ts
2
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' | 'SKILL_UNKNOWN_ALLOWED_TOOL' | 'SKILL_UNKNOWN_DEPENDENCY' | 'SKILL_CIRCULAR_DEPENDENCY' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE';
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_NOT_ALLOWED' | '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' | 'SKILL_UNKNOWN_ALLOWED_TOOL' | 'SKILL_UNKNOWN_DEPENDENCY' | 'SKILL_CIRCULAR_DEPENDENCY' | 'GOVERNANCE_FAILED' | 'RUN_SNAPSHOT_NOT_FOUND' | 'RUN_SNAPSHOT_EXPIRED' | 'RUN_SNAPSHOT_INCOMPATIBLE' | 'RUN_SNAPSHOT_SCHEMA_UNSUPPORTED' | 'RUN_TRACE_INCOMPATIBLE' | 'SESSION_INCOMPATIBLE' | 'SIGNATURE_MISSING' | 'SIGNATURE_MALFORMED' | 'SIGNATURE_UNTRUSTED_KEY' | 'SIGNATURE_MISMATCH' | 'SIGNATURE_UNSUPPORTED' | 'MCP_STDIO_SPAWN_FAILED' | 'MCP_STDIO_EXITED' | 'MCP_STDIO_TIMEOUT';
4
4
  /**
5
5
  * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
6
6
  * @stable
@@ -29,6 +29,27 @@ interface JsonSchema {
29
29
  [key: string]: unknown;
30
30
  }
31
31
  //#endregion
32
+ //#region src/contracts/pagination.d.ts
33
+ /**
34
+ * 全仓统一的游标分页形状。会话、消息、治理列表共用同一套,
35
+ * 不为每个存储端口各造一种(形状一多,调用方就得为每个端口重写一遍翻页逻辑)。
36
+ */
37
+ interface PageQuery {
38
+ /**
39
+ * 不透明续读位置,只能来自上一页的 `nextCursor`。
40
+ * 刻意不是数字 offset:追加型存储上并发追加会让 offset 错位,
41
+ * 而不透明串让实现方自己决定编码。
42
+ */
43
+ cursor?: string;
44
+ /** 本页最多返回多少条;缺省值由**存储实现**决定,不由调用方兜底 */
45
+ limit?: number;
46
+ }
47
+ /** 一页结果。`nextCursor` 缺席即已到末页,不用额外的 `hasMore` 布尔 */
48
+ interface Page<T> {
49
+ items: T[];
50
+ nextCursor?: string;
51
+ }
52
+ //#endregion
32
53
  //#region src/skill/manifest.d.ts
33
54
  type SkillInstallSource = {
34
55
  type: 'local';
@@ -91,6 +112,29 @@ interface VerifyResult {
91
112
  declare const SKILL_MANIFEST_FILE = "webskill.skill-manifest.json";
92
113
  /** managed root 下的锁定文件名(不参与 files 列表与 digest) */
93
114
  declare const SKILLS_LOCKFILE = "skills.lock.json";
115
+ /** 技能目录内的签名文件名(不参与 files 列表与 digest) */
116
+ declare const SKILL_SIGNATURE_FILE = "webskill.skill-signature.json";
117
+ /**
118
+ * 不参与 digest 的技能目录内文件。
119
+ *
120
+ * 这份名单原本在 node / browser / console / core 各抄一份,签名文件一旦漏抄一处,
121
+ * 写签名就会改变该处算出的 digest、让签名当场自我失效——而且只在「先签盘上的包、
122
+ * 再从盘上验」时才暴露。收成一处是为了让「漏抄」这件事不再可能发生。
123
+ */
124
+ declare const MANIFEST_EXCLUDED_FILES: ReadonlySet<string>;
125
+ /**
126
+ * 技能管理器的最小端口。
127
+ *
128
+ * 只声明**环境无关的调用方实际用到的方法**:治理层需要卸载技能,但不该因此
129
+ * 依赖 `@webskill/node` 的 `SkillManager` 类——那会把 `node:*` 类型拖进
130
+ * `/governance` 的 d.ts chunk(D21)。刻意不镜像 `SkillManager` 的全部方法,
131
+ * 否则只是换个名字保留同一份耦合。
132
+ *
133
+ * @stable
134
+ */
135
+ interface SkillManagerPort {
136
+ uninstall(name: string): Promise<void>;
137
+ }
94
138
  type Sha256Fn = (data: Uint8Array | string) => string | Promise<string>;
95
139
  /** 整体 digest:逐文件 "<path>:<sha256>\n" 拼接串(文件按 path 排序)的 sha256(hash 由调用方提供,可为 WebCrypto 异步实现) */
96
140
  declare function computeDigest(files: Array<{
@@ -144,6 +188,123 @@ interface FileSystemProvider {
144
188
  withRoot?(root: string): FileSystemProvider;
145
189
  }
146
190
  //#endregion
191
+ //#region src/skill/signature.d.ts
192
+ declare const SIGNATURE_SCHEMA_VERSION = 1;
193
+ /** `webskill.skill-signature.json` 的落盘形态 */
194
+ interface SkillSignature {
195
+ schemaVersion: number;
196
+ algorithm: 'ed25519';
197
+ /** 公钥 SHA-256 的前 16 字节 hex */
198
+ keyId: string;
199
+ /** base64url,raw 32 bytes */
200
+ publicKey: string;
201
+ /** base64url,raw 64 bytes */
202
+ signature: string;
203
+ signedAt: string;
204
+ }
205
+ /**
206
+ * 未签名包的处置策略。默认是 `warn`,0.4.0(D2)复核后维持不变:
207
+ * 默认信任库是空的,`deny` 之下未签名包报 `SIGNATURE_MISSING`、签名再正确也报
208
+ * `SIGNATURE_UNTRUSTED_KEY`——接受集为空,那不是更严的默认值而是恒失败的安装。
209
+ * `deny` 必须与装配好的 `TrustedKeyStore` 成对启用。
210
+ */
211
+ type UnsignedPolicy = 'allow' | 'warn' | 'deny';
212
+ interface TrustedKey {
213
+ keyId: string;
214
+ publicKey: string;
215
+ label: string;
216
+ addedAt: string;
217
+ }
218
+ interface TrustedKeyStore {
219
+ list(): Promise<TrustedKey[]>;
220
+ get(keyId: string): Promise<TrustedKey | undefined>;
221
+ add(key: Omit<TrustedKey, 'addedAt'>): Promise<void>;
222
+ remove(keyId: string): Promise<void>;
223
+ }
224
+ interface SignatureVerdict {
225
+ ok: boolean;
226
+ /** 未签名且策略放行时为 true;调用方据此决定是否发 warning 事件 */
227
+ unsigned: boolean;
228
+ /** 验签通过时是信任库里的 keyId */
229
+ keyId?: string;
230
+ /** 放行但需提醒的原因(英文,进审计与 UI) */
231
+ warning?: string;
232
+ }
233
+ /**
234
+ * 验签结论的审计投递口。governance 的 `FsAuditLog` 结构上满足它,
235
+ * 因此宿主可以直接传进来——core 不反向依赖 governance。
236
+ */
237
+ interface SignatureAuditSink {
238
+ append(event: {
239
+ type: string;
240
+ target: string;
241
+ data?: Record<string, unknown>;
242
+ }): Promise<unknown>;
243
+ }
244
+ /** 已导入的密钥句柄;真实 WebCrypto `CryptoKey` 结构上兼容 */
245
+ interface CryptoKeyLike {
246
+ readonly type: string;
247
+ readonly algorithm: {
248
+ readonly name: string;
249
+ };
250
+ }
251
+ /**
252
+ * 签名载荷:固定键序手写拼装,**不依赖 JSON.stringify 的属性顺序**
253
+ * (对象字面量顺序与运行时插入顺序不是同一件事,签验两侧字节必须逐字一致)。
254
+ *
255
+ * 载荷带 skill/version 而非裸 digest:只签 digest 时,同内容不同名的两个包
256
+ * 签名可以互换,等于允许把 A 技能的签名挪到 B 技能上。
257
+ */
258
+ declare function signaturePayloadBytes(manifest: SkillManifest): Uint8Array;
259
+ declare function keyIdOf(publicKey: Uint8Array): Promise<string>;
260
+ /** 从技能目录读签名文件;文件不存在返回 undefined(缺签名由策略层判定,不是错误) */
261
+ declare function readSkillSignature(fs: FileSystemProvider, skillRoot: string): Promise<SkillSignature | undefined>;
262
+ /**
263
+ * 验签。四种失败各自一个错误码,因为宿主的处置完全不同:
264
+ * 缺签名要引导选策略,坏文件要提示重下,不受信的 key 要引导添加密钥,
265
+ * 而验签不通过是安全事件,不提供「继续」。
266
+ *
267
+ * 包内自带的 publicKey **不产生任何信任**——它只是让「摘要不匹配」与
268
+ * 「公钥不受信」两种失败可区分。信任判定只认信任库里的 keyId。
269
+ */
270
+ declare function verifySkillSignature(input: {
271
+ manifest: SkillManifest;
272
+ signature: SkillSignature | undefined;
273
+ trustedKeys: TrustedKeyStore;
274
+ policy: {
275
+ unsigned: UnsignedPolicy;
276
+ };
277
+ }): Promise<SignatureVerdict>;
278
+ /**
279
+ * 为已生成 manifest 的技能产出签名。生产与测试走同一条路径——
280
+ * 只提供 CLI 会让测试无法覆盖真正被调用的代码。
281
+ *
282
+ * `publicKey` 必须显式传入:WebCrypto 没有「由私钥导出公钥」的 API,
283
+ * 密钥对的两半只能一起来。
284
+ */
285
+ declare function signSkill(input: {
286
+ manifest: SkillManifest;
287
+ /** 已导入的密钥句柄,或 pkcs8 DER 字节 */
288
+ privateKey: CryptoKeyLike | Uint8Array;
289
+ /** raw 32 字节公钥 */
290
+ publicKey: Uint8Array;
291
+ signedAt?: string;
292
+ }): Promise<SkillSignature>;
293
+ /**
294
+ * `FileSystemProvider` 后端的信任库:单个 JSON 文件,写入走原子替换。
295
+ *
296
+ * 「OPFS 还是 IndexedDB 还是宿主注入」不在这层回答——`FileSystemProvider`
297
+ * 已经是那层抽象,浏览器里落在哪由宿主注入的 fs 决定。
298
+ */
299
+ declare class FsTrustedKeyStore implements TrustedKeyStore {
300
+ #private;
301
+ constructor(fs: FileSystemProvider, path: string);
302
+ list(): Promise<TrustedKey[]>;
303
+ get(keyId: string): Promise<TrustedKey | undefined>;
304
+ add(key: Omit<TrustedKey, 'addedAt'>): Promise<void>;
305
+ remove(keyId: string): Promise<void>;
306
+ }
307
+ //#endregion
147
308
  //#region src/fs/memoryFs.d.ts
148
309
  /** 内存文件系统:路径一律规范化为 `/` 分隔,写入自动创建父目录 */
149
310
  declare class MemoryFS implements FileSystemProvider {
@@ -207,6 +368,22 @@ interface RemoteUrlPolicy {
207
368
  */
208
369
  declare function assertRemoteUrlAllowed(rawUrl: string, policy?: RemoteUrlPolicy): URL;
209
370
  //#endregion
371
+ //#region src/ui/types.d.ts
372
+ /**
373
+ * 声明式 UI 的节点:框架无关,技能脚本与 LLM 产出同一形状。
374
+ *
375
+ * 定义放在 core 而不是 ui/runtime:runtime 要用它做结构校验,ui 要用它做 catalog
376
+ * 语义校验,两者互不依赖。`@webskill/ui` 以同名 re-export,公开名不变。
377
+ */
378
+ interface UiSpecNode {
379
+ /** catalog 中声明过的组件名 */
380
+ component: string;
381
+ props?: Record<string, unknown>;
382
+ children?: UiSpecNode[];
383
+ /** 稳定 id(回放与 action 关联用;交互节点以此作为 actionId) */
384
+ id?: string;
385
+ }
386
+ //#endregion
210
387
  //#region src/skill/types.d.ts
211
388
  type SkillSource = 'local' | 'mcp' | 'generated' | 'installed';
212
389
  /**
@@ -405,7 +582,7 @@ declare function escapeXml(text: string): string;
405
582
  declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
406
583
  declare const xmlRenderer: CatalogRenderer;
407
584
  //#endregion
408
- //#region ../runtime/dist/types-AmKCKJn_.d.ts
585
+ //#region ../runtime/dist/types-7Wcg--Vh.d.ts
409
586
  //#region src/llm/streamTypes.d.ts
410
587
  /** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
411
588
  type LlmStreamEvent = {
@@ -420,9 +597,26 @@ type LlmStreamEvent = {
420
597
  };
421
598
  //#endregion
422
599
  //#region src/llm/types.d.ts
600
+ /**
601
+ * 消息内容分片。二进制一律 base64 内联:引用形态(URL / 句柄)需要生命周期管理,
602
+ * 不属于本批。代价是快照体积。
603
+ */
604
+ type LlmContentPart = {
605
+ type: 'text';
606
+ text: string;
607
+ } | {
608
+ type: 'image';
609
+ mimeType: string;
610
+ data: string;
611
+ } | {
612
+ type: 'file';
613
+ mimeType: string;
614
+ data: string;
615
+ name?: string;
616
+ };
423
617
  interface LlmMessage {
424
618
  role: 'system' | 'user' | 'assistant' | 'tool';
425
- content: string;
619
+ content: LlmContentPart[];
426
620
  /** role=tool 时必填 */
427
621
  toolCallId?: string;
428
622
  /** role=assistant 发起工具调用时携带 */
@@ -441,7 +635,7 @@ interface LlmToolCall {
441
635
  argumentsParseError?: string;
442
636
  }
443
637
  interface LlmResponse {
444
- content?: string;
638
+ content?: LlmContentPart[];
445
639
  toolCalls?: LlmToolCall[];
446
640
  raw?: unknown;
447
641
  }
@@ -568,14 +762,16 @@ interface RenderResultRequest {
568
762
  artifacts?: Artifact[];
569
763
  }
570
764
  /** A user action exposed by a generative UI surface. @experimental */
571
- interface UiSurfaceAction {
765
+ interface UiSpecActionCapability {
766
+ /** Matches the `id` of the interactive node that declares the action. */
572
767
  id: string;
573
- label: string;
574
768
  intent: 'submit' | 'cancel' | 'select' | 'download' | 'refresh';
575
- disabled?: boolean;
576
769
  /** Requests that the producing run waits for this action before continuing. @experimental */
577
770
  awaitResponse?: boolean;
578
- /** Runtime-generated action capability; model-provided values are never trusted. @experimental */
771
+ /**
772
+ * Runtime-generated action capability. Kept out of the node tree on purpose:
773
+ * the tree is model-writable, so a nonce carried inside it would be forgeable.
774
+ */
579
775
  nonce?: string;
580
776
  }
581
777
  /** A runtime-owned request for a user action on a rendered UI surface. @experimental */
@@ -583,7 +779,7 @@ interface UiSurfaceActionRequest {
583
779
  runId: string;
584
780
  surfaceId: string;
585
781
  actionId: string;
586
- intent: UiSurfaceAction['intent'];
782
+ intent: UiSpecActionCapability['intent'];
587
783
  nonce: string;
588
784
  }
589
785
  /** A structured action returned by a renderer to the waiting run. @experimental */
@@ -592,75 +788,26 @@ interface UiSurfaceActionResponse extends UiSurfaceActionRequest {
592
788
  cancelled?: boolean;
593
789
  }
594
790
  /** Serializable draft values for forms that belong to one interrupted run. @experimental */
595
- type UiSurfaceDrafts = Record<string, Record<string, unknown>>;
596
- /** A structured form field rendered inside a generative UI surface. @experimental */
597
- interface UiSurfaceFormField {
598
- name: string;
599
- label: string;
600
- type: 'text' | 'number' | 'date' | 'textarea' | 'select' | 'multi-select' | 'toggle' | 'file';
601
- required?: boolean;
602
- description?: string;
603
- defaultValue?: unknown;
604
- options?: Array<{
605
- label: string;
606
- value: unknown;
607
- }>;
608
- }
609
- /** Framework-neutral generative UI surface. @experimental */
610
- type UiSurface = {
611
- kind: 'form';
612
- id: string;
613
- title?: string;
614
- fields: UiSurfaceFormField[];
615
- actions: UiSurfaceAction[];
616
- } | {
617
- kind: 'chart';
618
- id: string;
619
- chart: ChartSpec;
620
- actions?: UiSurfaceAction[];
621
- } | {
622
- kind: 'table';
623
- id: string;
624
- columns: string[];
625
- rows: unknown[][];
626
- actions?: UiSurfaceAction[];
627
- } | {
628
- kind: 'metric';
629
- id: string;
630
- label: string;
631
- value: string | number;
632
- trend?: 'up' | 'down' | 'neutral';
633
- } | {
634
- kind: 'file';
635
- id: string;
636
- path: string;
637
- mimeType?: string;
638
- size?: number;
639
- actions?: UiSurfaceAction[];
640
- } | {
641
- kind: 'custom';
642
- id: string;
643
- component: string;
644
- props: unknown;
645
- actions?: UiSurfaceAction[];
646
- };
647
- /** A bounded mutation applied to an existing UI surface. @experimental */
648
- interface UiSurfacePatch {
791
+ type UiSpecDrafts = Record<string, Record<string, unknown>>;
792
+ /** A bounded mutation applied to an existing UI spec tree. @experimental */
793
+ interface UiSpecPatch {
649
794
  op: 'replace' | 'merge' | 'append';
650
795
  path: string;
651
796
  value: unknown;
652
797
  }
653
798
  /** Incremental lifecycle event for a framework-neutral generative UI surface. @experimental */
654
- type UiSurfaceEvent = {
799
+ type UiSpecEvent = {
655
800
  runId?: string;
656
801
  } & ({
657
802
  type: 'open';
658
- surface: UiSurface;
803
+ id: string;
804
+ node: UiSpecNode;
805
+ actions?: UiSpecActionCapability[];
659
806
  } | {
660
807
  type: 'patch';
661
808
  id: string;
662
809
  revision: number;
663
- operations: UiSurfacePatch[];
810
+ operations: UiSpecPatch[];
664
811
  } | {
665
812
  type: 'complete';
666
813
  id: string;
@@ -675,8 +822,10 @@ type UiSurfaceEvent = {
675
822
  id: string;
676
823
  });
677
824
  /** Persisted state of a generative UI surface. @experimental */
678
- interface UiSurfaceSnapshot {
679
- surface: UiSurface;
825
+ interface UiSpecSnapshot {
826
+ id: string;
827
+ node: UiSpecNode;
828
+ actions?: UiSpecActionCapability[];
680
829
  revision: number;
681
830
  status: 'active' | 'complete' | 'error' | 'cancelled';
682
831
  /** Immutable producing run; supplied on open to support session persistence and replay. */
@@ -699,7 +848,7 @@ interface UiBridge {
699
848
  /** 定义即可,阶段 7 消费 */
700
849
  renderResult?(input: RenderResultRequest): Promise<void>;
701
850
  /** Framework-neutral generative UI surface stream. @experimental */
702
- renderSurface?(event: UiSurfaceEvent): Promise<void>;
851
+ renderSurface?(event: UiSpecEvent): Promise<void>;
703
852
  /** Waits for an action declared with awaitResponse; optional for compatibility with legacy bridges. @experimental */
704
853
  requestSurfaceAction?(input: UiSurfaceActionRequest): Promise<UiSurfaceActionResponse>;
705
854
  /** Best-effort cleanup when a surface action wait times out or is cancelled. @experimental */
@@ -743,4 +892,4 @@ interface MemoryStore {
743
892
  transaction?<T>(scope: string, fn: (inner: MemoryStore) => Promise<T>): Promise<T>;
744
893
  }
745
894
  //#endregion
746
- export { SkillSource as $, DEFAULT_ARCHIVE_LIMITS as A, SKILL_NAME_PATTERN as B, UiSurfaceDrafts as C, renderCatalogJson as Ct, UiSurfaceSnapshot as D, validateSkills as Dt, UiSurfacePatch as E, unzipWithLimits as Et, MemoryFS as F, SkillDocument as G, SkillCatalog as H, RemoteUrlPolicy as I, SkillLocation as J, SkillInstallSource as K, SKILLS_LOCKFILE as L, FileStat as M, FileSystemProvider as N, ArchiveLimits as O, verifyManifest as Ot, JsonSchema as P, SkillReader as Q, SKILL_MANIFEST_FILE as R, UiSurfaceActionResponse as S, renderAvailableSkillsXml as St, UiSurfaceFormField as T, resolveInsideRoot as Tt, SkillCatalogEntry as U, SKILL_PACK_FILE as V, SkillDiscovery as W, SkillMetadata as X, SkillManifest as Y, SkillPackManifest as Z, RenderResultRequest as _, messageOf as _t, InteractionPolicy as a, assertRemoteUrlAllowed as at, UiSurfaceAction as b, parseSkillPackManifest as bt, LlmClient as c, buildCatalog as ct, LlmResponse as d, checkSkillRules as dt, SkillsLockfile as et, LlmStreamEvent as f, computeDigest as ft, RenderBlock as g, jsonRenderer as gt, MemoryStore as h, isValidSkillName as ht, FormField as i, WebSkillErrorCode as it, DiscoveryResult as j, CatalogRenderer as k, xmlRenderer as kt, LlmCompleteInput as l, buildManifest as lt, LlmToolSpec as m, exportSkills as mt, ArtifactStore as n, VerifyResult as nt, InteractionRequest as o, assertSafePathSegment as ot, LlmToolCall as p, escapeXml as pt, SkillIssue as q, ChartSpec as r, WebSkillError as rt, InteractionResponse as s, atomicWriteText as st, Artifact as t, ValidationReport as tt, LlmMessage as u, checkDependencyCycles as ut, UiBridge as v, normalizePath as vt, UiSurfaceEvent as w, resolveArchiveLimits as wt, UiSurfaceActionRequest as x, readResponseWithLimit as xt, UiSurface as y, parseSkillMarkdown as yt, SKILL_NAME_MAX_LENGTH as z };
895
+ export { SkillDocument as $, DEFAULT_ARCHIVE_LIMITS as A, jsonRenderer as At, RemoteUrlPolicy as B, resolveArchiveLimits as Bt, UiSpecPatch as C, buildManifest as Ct, ArchiveLimits as D, escapeXml as Dt, UiSurfaceActionResponse as E, computeDigest as Et, JsonSchema as F, parseSkillPackManifest as Ft, SKILL_NAME_PATTERN as G, validateSkills as Gt, SKILLS_LOCKFILE as H, signSkill as Ht, MANIFEST_EXCLUDED_FILES as I, readResponseWithLimit as It, SignatureAuditSink as J, xmlRenderer as Jt, SKILL_PACK_FILE as K, verifyManifest as Kt, MemoryFS as L, readSkillSignature as Lt, FileStat as M, messageOf as Mt, FileSystemProvider as N, normalizePath as Nt, CatalogRenderer as O, exportSkills as Ot, FsTrustedKeyStore as P, parseSkillMarkdown as Pt, SkillDiscovery as Q, Page as R, renderAvailableSkillsXml as Rt, UiSpecEvent as S, buildCatalog as St, UiSurfaceActionRequest as T, checkSkillRules as Tt, SKILL_MANIFEST_FILE as U, signaturePayloadBytes as Ut, SIGNATURE_SCHEMA_VERSION as V, resolveInsideRoot as Vt, SKILL_NAME_MAX_LENGTH as W, unzipWithLimits as Wt, SkillCatalog as X, SignatureVerdict as Y, SkillCatalogEntry as Z, RenderBlock as _, WebSkillError as _t, InteractionPolicy as a, SkillMetadata as at, UiSpecActionCapability as b, assertSafePathSegment as bt, LlmClient as c, SkillSignature as ct, LlmMessage as d, TrustedKey as dt, SkillInstallSource as et, LlmResponse as f, TrustedKeyStore as ft, MemoryStore as g, VerifyResult as gt, LlmToolSpec as h, ValidationReport as ht, FormField as i, SkillManifest as it, DiscoveryResult as j, keyIdOf as jt, CryptoKeyLike as k, isValidSkillName as kt, LlmCompleteInput as l, SkillSource as lt, LlmToolCall as m, UnsignedPolicy as mt, ArtifactStore as n, SkillLocation as nt, InteractionRequest as o, SkillPackManifest as ot, LlmStreamEvent as p, UiSpecNode as pt, SKILL_SIGNATURE_FILE as q, verifySkillSignature as qt, ChartSpec as r, SkillManagerPort as rt, InteractionResponse as s, SkillReader as st, Artifact as t, SkillIssue as tt, LlmContentPart as u, SkillsLockfile as ut, RenderResultRequest as v, WebSkillErrorCode as vt, UiSpecSnapshot as w, checkDependencyCycles as wt, UiSpecDrafts as x, atomicWriteText as xt, UiBridge as y, assertRemoteUrlAllowed as yt, PageQuery as z, renderCatalogJson as zt };