@webskill/sdk 0.7.0 → 0.9.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 (35) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +1 -1
  3. package/dist/browser.d.ts +151 -4
  4. package/dist/browser.js +269 -30
  5. package/dist/{catalogComponents-Dr5dFMAb-DKH_7VPI.js → catalogComponents-DfxxfUvn-T7Ic8QFV.js} +4026 -997
  6. package/dist/{dist-DnYG2-eY.js → dist-BQe1uglQ.js} +498 -118
  7. package/dist/{dist-8oQRa8Xz.js → dist-Bev6i6Ip.js} +102 -7
  8. package/dist/{dist-D0qW6e40.js → dist-CFmkV45C.js} +234 -27
  9. package/dist/{eventTypes-DjIQpt8Y-Bj3vghj4.js → eventTypes-DbOpAECr-BjcjZVms.js} +15 -2
  10. package/dist/governance.d.ts +24 -3
  11. package/dist/governance.js +30 -11
  12. package/dist/{index-BwsK9lGk.d.ts → index-DXNTIa-6.d.ts} +163 -6
  13. package/dist/{index-Ba3xFtfz.d.ts → index-lLcCpHE-.d.ts} +2 -2
  14. package/dist/{index-DkbABR43.d.ts → index-znZjobkr.d.ts} +144 -76
  15. package/dist/index.d.ts +11 -3
  16. package/dist/index.js +13 -4
  17. package/dist/mcp.d.ts +13 -2
  18. package/dist/mcp.js +19 -5
  19. package/dist/{memoryArtifactStore-52Zn9npI-BMPYwvoy.js → memoryArtifactStore-52Zn9npI-LbCQaqyx.js} +1 -1
  20. package/dist/node.d.ts +3 -3
  21. package/dist/node.js +6 -6
  22. package/dist/{openUiLibrary-Bdrji9qK-D2LxmM-a.js → openUiLibrary-DURlAxjk-Do_yqg3u.js} +3 -3
  23. package/dist/{skillVersionStore-Bl-ElD45-CWPvGvoq.d.ts → skillVersionStore-Bl-ElD45-dMJ8Ybhb.d.ts} +1 -1
  24. package/dist/{testing-CYTFqkDm.js → testing-Csg5ljNm.js} +2 -2
  25. package/dist/testing.d.ts +1 -1
  26. package/dist/testing.js +2 -2
  27. package/dist/{types-CcxRLdJG-DCXyw1US.d.ts → types-B3n0cMZu-BDhheIhX.d.ts} +54 -6
  28. package/dist/ui-react.d.ts +19 -6
  29. package/dist/ui-react.js +156 -84
  30. package/dist/ui-vue.d.ts +1 -1
  31. package/dist/ui-vue.js +2 -2
  32. package/dist/ui.d.ts +4 -4
  33. package/dist/ui.js +3 -3
  34. package/dist/{webskillLitCatalog-_mugzRHx-B_54vxum.js → webskillLitCatalog-DwTwSBFt-BG7kL-Es.js} +22 -3
  35. package/package.json +2 -2
@@ -1,6 +1,8 @@
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_NOT_ALLOWED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'TOOL_RESOLUTION_EXHAUSTED' | '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' | 'MCP_OAUTH_REQUIRED' | 'MCP_OAUTH_FAILED' | 'MCP_OAUTH_NOT_CONFIGURED' | 'PAGE_ACTION_OUT_OF_SCOPE' | 'PAGE_ACTION_STALE_REF' | 'PAGE_ACTION_DECLINED' | 'TS_RESOURCE_URL_REJECTED' | 'TS_TRANSPILER_UNAVAILABLE' | 'TS_TRANSPILE_FAILED' | 'TODO_LIST_INVALID' | 'TODO_ITEM_NOT_FOUND' | 'SKILL_GENERATION_DISABLED' | 'SKILL_GENERATION_LIMIT_EXCEEDED' | 'SKILL_GENERATION_VALIDATION_FAILED' | 'DELEGATION_UNAVAILABLE' | 'DELEGATION_IN_PROGRESS' | 'DELEGATION_BUDGET_EXCEEDED' | 'PROFILE_IMPORT_INVALID' | 'PROFILE_IMPORT_VERSION_UNSUPPORTED' | 'PROFILE_IMPORT_CREDENTIAL_REJECTED' | 'PROFILE_KEY_UNAVAILABLE' | 'DICTATION_UNAVAILABLE' | 'DICTATION_PERMISSION_DENIED' | 'DICTATION_FAILED' | 'PERCEPTION_NOT_ENABLED' | 'PERCEPTION_FAILED' | 'MODEL_IMAGE_UNSUPPORTED' | 'MODEL_TOOLS_UNSUPPORTED' | 'ATTACHMENT_TOO_LARGE' | 'ATTACHMENT_TYPE_REJECTED';
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' | 'SKILL_MANIFEST_PROTECTED' | 'VALIDATION_FAILED' | 'TOOL_NOT_FOUND' | 'TOOL_EXECUTION_FAILED' | 'NETWORK_BLOCKED' | 'TOOL_UNSUPPORTED' | 'TOOL_NOT_ALLOWED' | 'TOOL_SCHEMA_UNAVAILABLE' | 'TOOL_RESOLUTION_EXHAUSTED' | 'RUN_TIMEOUT' | 'RUN_MAX_TURNS_EXCEEDED' | 'RUN_FAILED' | 'RUN_CANCELLED' | 'RUN_INTERACTION_TIMEOUT' |
4
+ /** 历史里有未应答的工具调用,但当初为何中断已无从得知(分册 11 读取侧补齐) */
5
+ 'RUN_INTERRUPTED' | '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' | 'MCP_OAUTH_REQUIRED' | 'MCP_OAUTH_FAILED' | 'MCP_OAUTH_NOT_CONFIGURED' | 'PAGE_ACTION_OUT_OF_SCOPE' | 'PAGE_ACTION_STALE_REF' | 'PAGE_ACTION_DECLINED' | 'TS_RESOURCE_URL_REJECTED' | 'TS_TRANSPILER_UNAVAILABLE' | 'TS_TRANSPILE_FAILED' | 'TODO_LIST_INVALID' | 'TODO_ITEM_NOT_FOUND' | 'SKILL_GENERATION_DISABLED' | 'SKILL_GENERATION_LIMIT_EXCEEDED' | 'SKILL_GENERATION_VALIDATION_FAILED' | 'DELEGATION_UNAVAILABLE' | 'DELEGATION_IN_PROGRESS' | 'DELEGATION_BUDGET_EXCEEDED' | 'PROFILE_IMPORT_INVALID' | 'PROFILE_IMPORT_VERSION_UNSUPPORTED' | 'PROFILE_IMPORT_CREDENTIAL_REJECTED' | 'PROFILE_KEY_UNAVAILABLE' | 'DICTATION_UNAVAILABLE' | 'DICTATION_PERMISSION_DENIED' | 'DICTATION_FAILED' | 'PERCEPTION_NOT_ENABLED' | 'PERCEPTION_FAILED' | 'MODEL_IMAGE_UNSUPPORTED' | 'MODEL_TOOLS_UNSUPPORTED' | 'ATTACHMENT_TOO_LARGE' | 'ATTACHMENT_TYPE_REJECTED';
4
6
  /**
5
7
  * 所有公开 API 抛出的结构化错误,code 供上层可编程处理
6
8
  * @stable
@@ -327,6 +329,14 @@ declare class MemoryFS implements FileSystemProvider {
327
329
  }
328
330
  //#endregion
329
331
  //#region src/fs/atomicWrite.d.ts
332
+ /**
333
+ * 原子写的临时文件名后缀模式;列举/打包侧据此排除中断残留(0.9.0 分册 11)。
334
+ * 单一来源:不要在别处手写正则(AC-G10),复制正则必然漂移。
335
+ * @stable
336
+ */
337
+ declare const ATOMIC_TMP_SUFFIX_PATTERN: RegExp;
338
+ /** 该路径是否是 atomicWriteText 留下的临时文件 */
339
+ declare const isAtomicTempPath: (path: string) => boolean;
330
340
  /**
331
341
  * 原子写文本:先写临时文件再 rename(进程崩溃不留下半写文件;lockfile 等账本场景)。
332
342
  * 原子性强弱取决于 provider 的 rename 实现:NodeFS/MemoryFS 为真 rename;
@@ -471,6 +481,36 @@ declare function checkDependencyCycles(adjacency: Map<string, string[]>): {
471
481
  involved: Set<string>;
472
482
  };
473
483
  //#endregion
484
+ //#region src/skill/archiveShape.d.ts
485
+ /**
486
+ * 归档的三种合法形态。本轮 bug 的成因是「安装认三种、预览只认扁平」,
487
+ * 抽出后不允许再分叉(设计 19 §2.1)。
488
+ */
489
+ type SkillArchiveShape = 'pack-set' | 'flat' | 'nested-single' | 'invalid';
490
+ interface SkillArchiveDetection {
491
+ shape: SkillArchiveShape;
492
+ /** nested-single 时的顶层目录名(不含尾部斜杠),其余形态为 undefined */
493
+ rootDir?: string;
494
+ /** 无法判定时的原因,面向调用方,英文 */
495
+ reason?: string;
496
+ }
497
+ /**
498
+ * 按归档条目表判定包结构。
499
+ *
500
+ * 入参是条目表而不是文件系统:预览侧只有解压后的 entries,没有落盘的目录。
501
+ * 只看路径,不读内容——内容合法性由 checkSkillRules 负责,两者不重叠。
502
+ */
503
+ declare function detectSkillArchiveShape(entries: Iterable<string>): SkillArchiveDetection;
504
+ /** nested-single 时剥掉顶层目录,其余形态原样返回 */
505
+ declare function stripArchiveRoot<T>(entries: Record<string, T>, detection: SkillArchiveDetection): Record<string, T>;
506
+ /**
507
+ * 文件系统入口:安装管线拿到的是解压后的目录,不是条目表。
508
+ *
509
+ * 只探测判定所需的少量路径(不递归全量列举),再交给上面的纯函数——
510
+ * 判定规则仍然只有一份,这正是 S7 的目的。
511
+ */
512
+ declare function detectSkillArchiveShapeFromFs(fs: FileSystemProvider, contentDir: string): Promise<SkillArchiveDetection>;
513
+ //#endregion
474
514
  //#region src/skill/skillPack.d.ts
475
515
  /**
476
516
  * 技能包集(skill pack)格式与打包逻辑(node/browser 共用单一来源):
@@ -529,7 +569,9 @@ interface DiscoveryResult {
529
569
  }
530
570
  declare class SkillDiscovery {
531
571
  #private;
532
- constructor(fs: FileSystemProvider, roots: string[]);
572
+ constructor(fs: FileSystemProvider, roots: string[], options?: {
573
+ extraKnownSkillNames?: readonly string[];
574
+ });
533
575
  discover(): Promise<DiscoveryResult>;
534
576
  catalog(): Promise<{
535
577
  catalog: SkillCatalog;
@@ -548,8 +590,13 @@ interface ValidationReport {
548
590
  /**
549
591
  * 合规校验。内部直接复用 SkillDiscovery 的扫描逻辑,
550
592
  * 规则判定同样落在 checkSkillRules 单一来源上。
593
+ *
594
+ * `extraKnownSkillNames`:扫描范围之外已存在的技能名。安装时只扫刚解出来的那一个目录,
595
+ * 不告诉它库里还有谁,任何指向包外的 dependencies 都会被判成不存在。
551
596
  */
552
- declare function validateSkills(fs: FileSystemProvider, roots: string[]): Promise<ValidationReport>;
597
+ declare function validateSkills(fs: FileSystemProvider, roots: string[], options?: {
598
+ extraKnownSkillNames?: readonly string[];
599
+ }): Promise<ValidationReport>;
553
600
  //#endregion
554
601
  //#region src/skill/reader.d.ts
555
602
  /** 按技能名读取技能根目录内的文件,全部读取强制经过路径安全检查 */
@@ -582,7 +629,7 @@ declare function escapeXml(text: string): string;
582
629
  declare function renderAvailableSkillsXml(catalog: SkillCatalog): string;
583
630
  declare const xmlRenderer: CatalogRenderer;
584
631
  //#endregion
585
- //#region ../runtime/dist/types-CcxRLdJG.d.ts
632
+ //#region ../runtime/dist/types-B3n0cMZu.d.ts
586
633
  //#region src/llm/streamTypes.d.ts
587
634
  /** 流式 LLM 事件(OpenAI SSE / Vercel fullStream 统一映射) */
588
635
  type LlmStreamEvent = {
@@ -927,7 +974,8 @@ interface UiBridge {
927
974
  interface FormField {
928
975
  name: string;
929
976
  label: string;
930
- type: 'text' | 'number' | 'boolean' | 'select' | 'textarea' | 'file';
977
+ /** `password` 的值不进 paramHistory、不进行为记录、不落会话(FR-23.7) */
978
+ type: 'text' | 'number' | 'boolean' | 'select' | 'textarea' | 'file' | 'password';
931
979
  required?: boolean;
932
980
  description?: string;
933
981
  defaultValue?: unknown;
@@ -969,4 +1017,4 @@ interface MemoryStore {
969
1017
  transaction?<T>(scope: string, fn: (inner: MemoryStore) => Promise<T>): Promise<T>;
970
1018
  }
971
1019
  //#endregion
972
- export { SkillCatalog as $, ArchiveLimits as A, escapeXml as At, MemoryFS as B, readSkillSignature as Bt, UiSpecDrafts as C, assertSafePathSegment as Ct, UiSurfaceActionRequest as D, checkDependencyCycles as Dt, UiSpecSnapshot as E, buildManifest as Et, FileStat as F, messageOf as Ft, SKILLS_LOCKFILE as G, signSkill as Gt, PageQuery as H, renderCatalogJson as Ht, FileSystemProvider as I, normalizePath as It, SKILL_NAME_PATTERN as J, validateSkills as Jt, SKILL_MANIFEST_FILE as K, signaturePayloadBytes as Kt, FsTrustedKeyStore as L, parseSkillMarkdown as Lt, CryptoKeyLike as M, isValidSkillName as Mt, DEFAULT_ARCHIVE_LIMITS as N, jsonRenderer as Nt, UiSurfaceActionResponse as O, checkSkillRules as Ot, DiscoveryResult as P, keyIdOf as Pt, SignatureVerdict as Q, JsonSchema as R, parseSkillPackManifest as Rt, UiSpecActionCapability as S, assertRemoteUrlAllowed as St, UiSpecPatch as T, buildCatalog as Tt, RemoteUrlPolicy as U, resolveArchiveLimits as Ut, Page as V, renderAvailableSkillsXml as Vt, SIGNATURE_SCHEMA_VERSION as W, resolveInsideRoot as Wt, SKILL_SIGNATURE_FILE as X, verifySkillSignature as Xt, SKILL_PACK_FILE as Y, verifyManifest as Yt, SignatureAuditSink as Z, xmlRenderer as Zt, MemoryStore as _, UnsignedPolicy as _t, InteractionOrigin as a, SkillLocation as at, SkillCandidateMarker as b, WebSkillError as bt, InteractionResponse as c, SkillMetadata as ct, LlmContentPart as d, SkillSignature as dt, SkillCatalogEntry as et, LlmMessage as f, SkillSource as ft, LlmToolSpec as g, UiSpecNode as gt, LlmToolCall as h, TrustedKeyStore as ht, FormField as i, SkillIssue as it, CatalogRenderer as j, exportSkills as jt, extractSkillCandidate as k, computeDigest as kt, LlmClient as l, SkillPackManifest as lt, LlmStreamEvent as m, TrustedKey as mt, ArtifactStore as n, SkillDocument as nt, InteractionPolicy as o, SkillManagerPort as ot, LlmResponse as p, SkillsLockfile as pt, SKILL_NAME_MAX_LENGTH as q, unzipWithLimits as qt, ChartSpec as r, SkillInstallSource as rt, InteractionRequest as s, SkillManifest as st, Artifact as t, SkillDiscovery as tt, LlmCompleteInput as u, SkillReader as ut, RenderBlock as v, ValidationReport as vt, UiSpecEvent as w, atomicWriteText as wt, UiBridge as x, WebSkillErrorCode as xt, RenderResultRequest as y, VerifyResult as yt, MANIFEST_EXCLUDED_FILES as z, readResponseWithLimit as zt };
1020
+ export { SignatureVerdict as $, stripArchiveRoot as $t, ATOMIC_TMP_SUFFIX_PATTERN as A, checkDependencyCycles as At, MANIFEST_EXCLUDED_FILES as B, keyIdOf as Bt, UiSpecDrafts as C, WebSkillError as Ct, UiSurfaceActionRequest as D, atomicWriteText as Dt, UiSpecSnapshot as E, assertSafePathSegment as Et, DiscoveryResult as F, escapeXml as Ft, SIGNATURE_SCHEMA_VERSION as G, readResponseWithLimit as Gt, Page as H, normalizePath as Ht, FileStat as I, exportSkills as It, SKILL_NAME_MAX_LENGTH as J, renderCatalogJson as Jt, SKILLS_LOCKFILE as K, readSkillSignature as Kt, FileSystemProvider as L, isAtomicTempPath as Lt, CatalogRenderer as M, computeDigest as Mt, CryptoKeyLike as N, detectSkillArchiveShape as Nt, UiSurfaceActionResponse as O, buildCatalog as Ot, DEFAULT_ARCHIVE_LIMITS as P, detectSkillArchiveShapeFromFs as Pt, SignatureAuditSink as Q, signaturePayloadBytes as Qt, FsTrustedKeyStore as R, isValidSkillName as Rt, UiSpecActionCapability as S, VerifyResult as St, UiSpecPatch as T, assertRemoteUrlAllowed as Tt, PageQuery as U, parseSkillMarkdown as Ut, MemoryFS as V, messageOf as Vt, RemoteUrlPolicy as W, parseSkillPackManifest as Wt, SKILL_PACK_FILE as X, resolveInsideRoot as Xt, SKILL_NAME_PATTERN as Y, resolveArchiveLimits as Yt, SKILL_SIGNATURE_FILE as Z, signSkill as Zt, MemoryStore as _, TrustedKey as _t, InteractionOrigin as a, SkillDocument as at, SkillCandidateMarker as b, UnsignedPolicy as bt, InteractionResponse as c, SkillLocation as ct, LlmContentPart as d, SkillMetadata as dt, unzipWithLimits as en, SkillArchiveDetection as et, LlmMessage as f, SkillPackManifest as ft, LlmToolSpec as g, SkillsLockfile as gt, LlmToolCall as h, SkillSource as ht, FormField as i, xmlRenderer as in, SkillDiscovery as it, ArchiveLimits as j, checkSkillRules as jt, extractSkillCandidate as k, buildManifest as kt, LlmClient as l, SkillManagerPort as lt, LlmStreamEvent as m, SkillSignature as mt, ArtifactStore as n, verifyManifest as nn, SkillCatalog as nt, InteractionPolicy as o, SkillInstallSource as ot, LlmResponse as p, SkillReader as pt, SKILL_MANIFEST_FILE as q, renderAvailableSkillsXml as qt, ChartSpec as r, verifySkillSignature as rn, SkillCatalogEntry as rt, InteractionRequest as s, SkillIssue as st, Artifact as t, validateSkills as tn, SkillArchiveShape as tt, LlmCompleteInput as u, SkillManifest as ut, RenderBlock as v, TrustedKeyStore as vt, UiSpecEvent as w, WebSkillErrorCode as wt, UiBridge as x, ValidationReport as xt, RenderResultRequest as y, UiSpecNode as yt, JsonSchema as z, jsonRenderer as zt };
@@ -1,7 +1,7 @@
1
- import { C as UiSpecDrafts, D as UiSurfaceActionRequest, E as UiSpecSnapshot, O as UiSurfaceActionResponse, S as UiSpecActionCapability, c as InteractionResponse, gt as UiSpecNode, s as InteractionRequest, w as UiSpecEvent, x as UiBridge, y as RenderResultRequest } from "./types-CcxRLdJG-DCXyw1US.js";
2
- import { b as InteractionSpecLabels } from "./index-BwsK9lGk.js";
1
+ import { C as UiSpecDrafts, D as UiSurfaceActionRequest, E as UiSpecSnapshot, O as UiSurfaceActionResponse, S as UiSpecActionCapability, c as InteractionResponse, s as InteractionRequest, w as UiSpecEvent, x as UiBridge, y as RenderResultRequest, yt as UiSpecNode } from "./types-B3n0cMZu-BDhheIhX.js";
2
+ import { E as InteractionSpecLabels, R as SurfaceFormTexts } from "./index-DXNTIa-6.js";
3
3
  import { z } from "zod";
4
- import { ComponentType, ReactNode } from "react";
4
+ import React$1, { ComponentType, ReactNode } from "react";
5
5
  import "react/jsx-runtime";
6
6
  //#region ../../node_modules/.pnpm/@json-render+core@0.19.0_zod@4.4.3/node_modules/@json-render/core/dist/store-utils-D98Czbil.d.ts
7
7
  /**
@@ -274,6 +274,12 @@ interface ReactBridgeStateOptions {
274
274
  onSurfaceDraftChange?(runId: string, surfaceId: string, value: Record<string, unknown>): Promise<void> | void;
275
275
  /** 覆盖默认的 console.warn 上报(测试与宿主遥测用)。@experimental */
276
276
  onDroppedSurfaceAction?(warning: DroppedSurfaceActionWarning): void;
277
+ /**
278
+ * run 结果渲染请求按 runId 派发(FR-12.1)。
279
+ * `latestResult` 是全局单槽:多 run 并发时会被后一个 run 覆盖,消费方无法据此判断
280
+ * blocks 归属;订阅本回调的引擎按 runId 缓存自己的渲染产物。
281
+ */
282
+ onRenderResult?(runId: string, request: RenderResultRequest): void;
277
283
  }
278
284
  /**
279
285
  * React 桥接状态:UiBridge 实现 + useSyncExternalStore 兼容订阅。
@@ -433,7 +439,7 @@ interface JsonRenderSpecSurfaceProps {
433
439
  * `vercel` 档:同一份 catalog 声明树交给 json-render 的 Registry 渲染。
434
440
  * `@json-render/*` 是 optional peer,未安装时给出英文说明而不是空白。
435
441
  */
436
- declare function JsonRenderSpecSurface({ spec, surfaceId, actions, onAction }: JsonRenderSpecSurfaceProps): import("react").JSX.Element | null;
442
+ declare function JsonRenderSpecSurface({ spec, surfaceId, actions, onAction }: JsonRenderSpecSurfaceProps): import("react").JSX.Element;
437
443
  //#endregion
438
444
  //#region src/catalog/jsonRenderRegistry.d.ts
439
445
  /** catalog 的 action 名与 `UiSpecActionCapability['intent']` 一一对应 */
@@ -497,7 +503,7 @@ interface OpenUiSpecSurfaceProps {
497
503
  * `openui` 档:同一份 catalog 声明树经 openui-lang 交给 OpenUI 的 Renderer。
498
504
  * `@openuidev/react-lang` 是 optional peer,未安装时给出英文说明而不是空白。
499
505
  */
500
- declare function OpenUiSpecSurface({ spec, surfaceId, actions, onAction }: OpenUiSpecSurfaceProps): import("react").JSX.Element | null;
506
+ declare function OpenUiSpecSurface({ spec, surfaceId, actions, onAction }: OpenUiSpecSurfaceProps): import("react").JSX.Element;
501
507
  //#endregion
502
508
  //#region src/catalog/catalogComponents.d.ts
503
509
  type CatalogNodeProps = {
@@ -511,4 +517,11 @@ type CatalogNodeProps = {
511
517
  */
512
518
  declare const catalogComponentImpls: Record<string, (input: CatalogNodeProps) => ReactNode>;
513
519
  //#endregion
514
- export { type CatalogNodeProps, type CustomSurfaceActionEvent, type DroppedSurfaceActionWarning, InteractionForm, type JsonRenderActionDispatch, JsonRenderSpecSurface, type JsonRenderSpecSurfaceProps, NATIVE_SPEC_COMPONENTS, NativeSpecSurface, type NativeSpecSurfaceProps, OpenUiSpecSurface, type OpenUiSpecSurfaceProps, ReactBridgeState, type ReactBridgeStateOptions, type RegisteredSurfaceProps, ResultBlocks, SpecInteractionChannel, type SpecInteractionSession, StreamingText, type SurfaceRegistration, SurfaceRegistry, type UiSurfaceActionEvent, UiSurfaceList, type UiSurfaceListProps, UiSurfaceSnapshotList, type UiSurfaceSnapshotListProps, UiSurfaceStore, catalogComponentImpls, createJsonRenderRegistry, probeJsonRenderAvailability };
520
+ //#region src/catalog/surfaceFormTexts.d.ts
521
+ declare function useSurfaceFormTexts(): SurfaceFormTexts;
522
+ declare function SurfaceFormTextsProvider({ texts, children }: {
523
+ texts?: Partial<SurfaceFormTexts> | undefined;
524
+ children: ReactNode;
525
+ }): import("react").JSX.Element;
526
+ //#endregion
527
+ export { type CatalogNodeProps, type CustomSurfaceActionEvent, type DroppedSurfaceActionWarning, InteractionForm, type JsonRenderActionDispatch, JsonRenderSpecSurface, type JsonRenderSpecSurfaceProps, NATIVE_SPEC_COMPONENTS, NativeSpecSurface, type NativeSpecSurfaceProps, OpenUiSpecSurface, type OpenUiSpecSurfaceProps, ReactBridgeState, type ReactBridgeStateOptions, type RegisteredSurfaceProps, ResultBlocks, SpecInteractionChannel, type SpecInteractionSession, StreamingText, SurfaceFormTextsProvider, type SurfaceRegistration, SurfaceRegistry, type UiSurfaceActionEvent, UiSurfaceList, type UiSurfaceListProps, UiSurfaceSnapshotList, type UiSurfaceSnapshotListProps, UiSurfaceStore, catalogComponentImpls, createJsonRenderRegistry, probeJsonRenderAvailability, useSurfaceFormTexts };
package/dist/ui-react.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { r as __exportAll$1 } from "./rolldown-runtime-BOF7iYI8.js";
2
- import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
3
- import { Et as validateUiSpecNode, Tt as validateUiSpecEvent } from "./dist-D0qW6e40.js";
4
- import { B as toOpenUiSpecLang, I as shapeInteractionValue, O as interactionToFormModel, P as renderMiniChart, Q as chartSpecFromProps, g as applySuggestion, k as interactionToUiSpec, nt as uiCatalog, tt as renderMiniMarkdown, x as collectValues, z as toJsonRenderSpec } from "./dist-DnYG2-eY.js";
5
- import { C as Markdown, S as Input, _ as DataTable, a as SpecProgress, b as DropdownMenuContent, c as SurfaceButton, d as catalogComponentImpls, f as str, g as Button, h as Badge, i as SpecGrid, l as SurfaceField, m as useSurfaceForm, n as CatalogSurfaceProvider, o as SpecTabs, p as useCatalogSurfaceForm, r as EChart, s as SpecTimeline, u as SurfaceFormButtons, v as DropdownMenu, w as Separator, x as DropdownMenuTrigger, y as DropdownMenuCheckboxItem } from "./catalogComponents-Dr5dFMAb-DKH_7VPI.js";
2
+ import { h as WebSkillError } from "./dist-Bev6i6Ip.js";
3
+ import { Ot as validateUiSpecEvent, kt as validateUiSpecNode } from "./dist-CFmkV45C.js";
4
+ import { F as normalizeColumnWidths, M as interactionToUiSpec, R as renderMiniChart, U as toJsonRenderSpec, W as toOpenUiSpecLang, Z as DEFAULT_SURFACE_FORM_TEXTS, ct as renderMiniMarkdown, dt as shapeInteractionValue, ft as uiCatalog, it as chartSpecFromProps, ot as interactionToFormModel, w as collectValues, y as applySuggestion } from "./dist-BQe1uglQ.js";
5
+ import { C as DropdownMenuContent, D as Separator, E as Markdown, S as DropdownMenuCheckboxItem, T as Input, _ as useSurfaceFormTexts, a as SpecProgress, b as DataTable, c as SurfaceButton, d as SurfaceFormButtons, f as SurfaceFormTextsProvider, g as useSurfaceForm, h as useCatalogSurfaceForm, i as SpecGrid, l as SurfaceField, m as str, n as CatalogSurfaceProvider, o as SpecTabs, p as catalogComponentImpls, r as EChart, s as SpecTimeline, u as SurfaceFieldArray, v as Badge, w as DropdownMenuTrigger, x as DropdownMenu, y as Button } from "./catalogComponents-DfxxfUvn-T7Ic8QFV.js";
6
6
  import { z } from "zod";
7
7
  import * as React$1 from "react";
8
8
  import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
@@ -6521,9 +6521,11 @@ var ReactBridgeState = class {
6521
6521
  #surfaceDrafts = /* @__PURE__ */ new Map();
6522
6522
  #onSurfaceDraftChange;
6523
6523
  #onDroppedSurfaceAction;
6524
+ #onRenderResult;
6524
6525
  constructor(options = {}) {
6525
6526
  this.#onSurfaceDraftChange = options.onSurfaceDraftChange;
6526
6527
  this.#onDroppedSurfaceAction = options.onDroppedSurfaceAction;
6528
+ this.#onRenderResult = options.onRenderResult;
6527
6529
  this.surfaceStore.subscribe(() => this.#emit());
6528
6530
  }
6529
6531
  get surfaceSnapshots() {
@@ -6580,6 +6582,7 @@ var ReactBridgeState = class {
6580
6582
  }
6581
6583
  async renderResult(input) {
6582
6584
  this.latestResult = input;
6585
+ this.#onRenderResult?.(input.runId, input);
6583
6586
  this.#emit();
6584
6587
  }
6585
6588
  async renderSurface(event) {
@@ -6819,7 +6822,7 @@ function InteractionForm({ bridge }) {
6819
6822
  id: `webskill-error-${control.name}`,
6820
6823
  role: "alert",
6821
6824
  className: "webskill-form__error",
6822
- children: "This field is required"
6825
+ children: DEFAULT_SURFACE_FORM_TEXTS.required
6823
6826
  }) : null
6824
6827
  ]
6825
6828
  }, control.name)),
@@ -6912,15 +6915,63 @@ function StreamingText({ bridge }) {
6912
6915
  });
6913
6916
  }
6914
6917
  /**
6918
+ * 渲染前的逐节点降级(FR-23.3)。
6919
+ *
6920
+ * 三档过去都是「整树 validate,失败即整块换成一行红字」——一个节点的一个 prop 不合法
6921
+ * 就让整个 surface 消失。到了渲染层这份 spec 可能来自快照重放或更早的语法版本,
6922
+ * 此刻整块拒绝而 run 还在等它的响应,正是 AC-G11 要防的「整块消失」。
6923
+ */
6924
+ function useSanitizedSpec(spec) {
6925
+ return useMemo(() => uiCatalog.sanitize(spec), [spec]);
6926
+ }
6927
+ const isOutOfCatalog = (degradation) => degradation.kind === "unknown-component";
6928
+ /**
6929
+ * 越界组件名的响亮拒绝。
6930
+ *
6931
+ * 它是**对 spec 本身**的判定,与渲染器装没装无关,所以要渲染在可选依赖的门禁之前——
6932
+ * 放到门禁后面,未安装该档时这条越界信号就消失了。
6933
+ */
6934
+ function SurfaceRejectionAlert({ degradations }) {
6935
+ const rejected = degradations.filter(isOutOfCatalog);
6936
+ if (rejected.length === 0) return null;
6937
+ return /* @__PURE__ */ jsxs("div", {
6938
+ role: "alert",
6939
+ className: "webskill-surface--error text-sm text-destructive",
6940
+ children: ["Invalid UI spec: ", rejected.map((item) => `${item.path}: ${item.detail}`).join("; ")]
6941
+ });
6942
+ }
6943
+ /** 其余降级的中性说明(AC-23.8):不是错误,是「这个档 / 这份 spec 有一部分做不到」 */
6944
+ function SurfaceSimplifiedNote({ degradations }) {
6945
+ const simplified = degradations.filter((degradation) => !isOutOfCatalog(degradation));
6946
+ if (simplified.length === 0) return null;
6947
+ return /* @__PURE__ */ jsx("div", {
6948
+ role: "note",
6949
+ "data-webskill-degraded": simplified.length,
6950
+ className: "webskill-surface--unsupported text-xs text-muted",
6951
+ children: simplified.map((item) => `${item.path} (${item.kind})`).join("; ")
6952
+ });
6953
+ }
6954
+ /** 两级合并渲染;可选依赖有门禁的档要分开用上面两个 */
6955
+ function SurfaceDegradationNote({ degradations }) {
6956
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SurfaceRejectionAlert, { degradations }), /* @__PURE__ */ jsx(SurfaceSimplifiedNote, { degradations })] });
6957
+ }
6958
+ /**
6915
6959
  * catalog `Table` 节点的渲染实现:排序 / 筛选 / 分页 / 列显隐 / 虚拟滚动。
6916
6960
  * 这些是宿主侧的呈现能力,不进 catalog props——模型只声明 columns 与 rows。
6917
6961
  * 它们都带 `data-webskill-host-control`,跨渲染器语义对括据此排除宿主控件。
6918
6962
  */
6919
- function SpecTable({ columns, rows, label }) {
6963
+ function SpecTable({ columns, rows, label, columnWidths, onDegraded }) {
6920
6964
  const [sorting, setSorting] = useState([]);
6921
6965
  const [globalFilter, setGlobalFilter] = useState("");
6922
6966
  const [columnVisibility, setColumnVisibility] = useState({});
6923
6967
  const scrollRef = useRef(null);
6968
+ const normalized = normalizeColumnWidths(columnWidths, columns.length);
6969
+ const weightTotal = normalized.weights.reduce((sum, weight) => sum + weight, 0);
6970
+ const widthPercents = normalized.weights.map((weight) => weightTotal > 0 ? weight / weightTotal * 100 : 0);
6971
+ const rejected = normalized.rejected;
6972
+ useEffect(() => {
6973
+ if (rejected !== void 0) onDegraded?.(rejected);
6974
+ }, [rejected, onDegraded]);
6924
6975
  const table = useReactTable({
6925
6976
  data: rows,
6926
6977
  columns: columns.map((header, index) => ({
@@ -6983,30 +7034,34 @@ function SpecTable({ columns, rows, label }) {
6983
7034
  /* @__PURE__ */ jsxs(DataTable, {
6984
7035
  "aria-label": label,
6985
7036
  containerClassName: "webskill-surface__table-scroll",
6986
- children: [/* @__PURE__ */ jsx("thead", {
6987
- className: "webskill-surface__table-header",
6988
- children: /* @__PURE__ */ jsx("tr", { children: table.getFlatHeaders().map((header) => /* @__PURE__ */ jsx("th", {
6989
- scope: "col",
6990
- ...header.column.id === "selection" ? { "data-webskill-host-control": "" } : {},
6991
- "aria-sort": header.column.getIsSorted() === "asc" ? "ascending" : header.column.getIsSorted() === "desc" ? "descending" : "none",
6992
- children: header.column.getCanSort() ? /* @__PURE__ */ jsx("button", {
6993
- type: "button",
6994
- "data-webskill-host-control": "",
6995
- onClick: header.column.getToggleSortingHandler(),
6996
- children: flexRender(header.column.columnDef.header, header.getContext())
6997
- }) : flexRender(header.column.columnDef.header, header.getContext())
6998
- }, header.id)) })
6999
- }), /* @__PURE__ */ jsx("tbody", {
7000
- ref: scrollRef,
7001
- className: "webskill-surface__table-body",
7002
- children: renderedRows.map((virtualRow) => {
7003
- const row = modelRows[virtualRow.index];
7004
- return /* @__PURE__ */ jsx("tr", { children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
7005
- ...cell.column.id === "selection" ? { "data-webskill-host-control": "" } : {},
7006
- children: flexRender(cell.column.columnDef.cell, cell.getContext())
7007
- }, cell.id)) }, row.id);
7037
+ children: [
7038
+ /* @__PURE__ */ jsx("colgroup", { children: widthPercents.map((percent, index) => /* @__PURE__ */ jsx("col", { style: { width: `${percent}%` } }, index)) }),
7039
+ /* @__PURE__ */ jsx("thead", {
7040
+ className: "webskill-surface__table-header",
7041
+ children: /* @__PURE__ */ jsx("tr", { children: table.getFlatHeaders().map((header) => /* @__PURE__ */ jsx("th", {
7042
+ scope: "col",
7043
+ ...header.column.id === "selection" ? { "data-webskill-host-control": "" } : {},
7044
+ "aria-sort": header.column.getIsSorted() === "asc" ? "ascending" : header.column.getIsSorted() === "desc" ? "descending" : "none",
7045
+ children: header.column.getCanSort() ? /* @__PURE__ */ jsx("button", {
7046
+ type: "button",
7047
+ "data-webskill-host-control": "",
7048
+ onClick: header.column.getToggleSortingHandler(),
7049
+ children: flexRender(header.column.columnDef.header, header.getContext())
7050
+ }) : flexRender(header.column.columnDef.header, header.getContext())
7051
+ }, header.id)) })
7052
+ }),
7053
+ /* @__PURE__ */ jsx("tbody", {
7054
+ ref: scrollRef,
7055
+ className: "webskill-surface__table-body",
7056
+ children: renderedRows.map((virtualRow) => {
7057
+ const row = modelRows[virtualRow.index];
7058
+ return /* @__PURE__ */ jsx("tr", { children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
7059
+ ...cell.column.id === "selection" ? { "data-webskill-host-control": "" } : {},
7060
+ children: flexRender(cell.column.columnDef.cell, cell.getContext())
7061
+ }, cell.id)) }, row.id);
7062
+ })
7008
7063
  })
7009
- })]
7064
+ ]
7010
7065
  }),
7011
7066
  /* @__PURE__ */ jsxs("div", {
7012
7067
  className: "webskill-surface__table-pagination",
@@ -7096,11 +7151,17 @@ function renderNode(node, context, key, scope) {
7096
7151
  }) : null
7097
7152
  ]
7098
7153
  }, key);
7099
- case "Table": return /* @__PURE__ */ jsx(SpecTable, {
7100
- columns: Array.isArray(props["columns"]) ? props["columns"] : [],
7101
- rows: Array.isArray(props["rows"]) ? props["rows"] : [],
7102
- label: str(props, "title", "Data")
7103
- }, key);
7154
+ case "Table": {
7155
+ const columns = Array.isArray(props["columns"]) ? props["columns"] : [];
7156
+ const rows = Array.isArray(props["rows"]) ? props["rows"] : [];
7157
+ const columnWidths = Array.isArray(props["columnWidths"]) ? props["columnWidths"] : void 0;
7158
+ return /* @__PURE__ */ jsx(SpecTable, {
7159
+ columns,
7160
+ rows,
7161
+ label: str(props, "title", "Data"),
7162
+ ...columnWidths ? { columnWidths } : {}
7163
+ }, key);
7164
+ }
7104
7165
  case "Chart": return /* @__PURE__ */ jsx(EChart, { chart: chartSpecFromProps(props) }, key);
7105
7166
  case "Tabs": return /* @__PURE__ */ jsx(SpecTabs, {
7106
7167
  props,
@@ -7117,7 +7178,7 @@ function renderNode(node, context, key, scope) {
7117
7178
  children: [/* @__PURE__ */ jsx("span", {
7118
7179
  className: "text-ink",
7119
7180
  children: str(props, "label", str(props, "path"))
7120
- }), /* @__PURE__ */ jsx(Button, {
7181
+ }), context.readOnly ? null : /* @__PURE__ */ jsx(Button, {
7121
7182
  size: "sm",
7122
7183
  variant: "secondary",
7123
7184
  "data-webskill-surface-action": context.resolveActionId("download", node.id),
@@ -7150,6 +7211,11 @@ function renderNode(node, context, key, scope) {
7150
7211
  props,
7151
7212
  scope
7152
7213
  }, key);
7214
+ case "FieldArray": return /* @__PURE__ */ jsx(SurfaceFieldArray, {
7215
+ form: context,
7216
+ props,
7217
+ scope
7218
+ }, key);
7153
7219
  case "Button": return /* @__PURE__ */ jsx(SurfaceButton, {
7154
7220
  form: context,
7155
7221
  props,
@@ -7204,29 +7270,35 @@ function renderNode(node, context, key, scope) {
7204
7270
  * 节点树取代六类 surface 后,这里是 native 档唯一的渲染实现。
7205
7271
  */
7206
7272
  function NativeSpecSurface({ surfaceId, spec, actions, registry, runId, draft, onAction, onDraftChange, shell = "card" }) {
7273
+ const sanitized = useSanitizedSpec(spec);
7274
+ const form = useSurfaceForm({
7275
+ surfaceId,
7276
+ spec: sanitized.node ?? spec,
7277
+ actions,
7278
+ runId,
7279
+ draft,
7280
+ onAction,
7281
+ onDraftChange
7282
+ });
7207
7283
  const context = {
7208
- ...useSurfaceForm({
7209
- surfaceId,
7210
- spec,
7211
- actions,
7212
- runId,
7213
- draft,
7214
- onAction,
7215
- onDraftChange
7216
- }),
7284
+ ...form,
7217
7285
  registry,
7218
7286
  onAction
7219
7287
  };
7220
- const validation = uiCatalog.validate(spec);
7221
- if (!validation.ok) return /* @__PURE__ */ jsxs("div", {
7222
- role: "alert",
7223
- className: "webskill-surface--error text-sm text-destructive",
7224
- children: ["Invalid UI spec: ", validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ")]
7225
- });
7226
- return /* @__PURE__ */ jsx("div", {
7288
+ const texts = useSurfaceFormTexts();
7289
+ const { node, degradations } = sanitized;
7290
+ return /* @__PURE__ */ jsxs("div", {
7227
7291
  className: shell === "none" ? "webskill-surface--spec" : "webskill-surface webskill-surface--spec",
7228
7292
  "data-testid": "native-spec-surface",
7229
- children: renderNode(spec, context, "root")
7293
+ children: [
7294
+ node ? renderNode(node, context, "root") : null,
7295
+ form.readOnly && actions.length > 0 ? /* @__PURE__ */ jsx("p", {
7296
+ "data-testid": "surface-readonly-note",
7297
+ className: "mt-2 text-xs text-muted",
7298
+ children: texts.readOnlySnapshot
7299
+ }) : null,
7300
+ /* @__PURE__ */ jsx(SurfaceDegradationNote, { degradations })
7301
+ ]
7230
7302
  });
7231
7303
  }
7232
7304
  function Surface({ snapshot, registry, onAction, drafts, onDraftChange }) {
@@ -7324,27 +7396,27 @@ function JsonRenderSpecSurface({ spec, surfaceId, actions, onAction }) {
7324
7396
  cancelled = true;
7325
7397
  };
7326
7398
  }, []);
7327
- const validation = uiCatalog.validate(spec);
7328
- if (!validation.ok) return /* @__PURE__ */ jsxs("div", {
7329
- role: "alert",
7330
- className: "webskill-surface--error text-sm text-destructive",
7331
- children: ["Invalid UI spec: ", validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ")]
7332
- });
7333
- if (unavailable) return /* @__PURE__ */ jsx("div", {
7399
+ const sanitized = useSanitizedSpec(spec);
7400
+ const rejection = /* @__PURE__ */ jsx(SurfaceRejectionAlert, { degradations: sanitized.degradations });
7401
+ if (unavailable) return /* @__PURE__ */ jsxs(Fragment$1, { children: [rejection, /* @__PURE__ */ jsx("div", {
7334
7402
  role: "alert",
7335
7403
  className: "webskill-surface--unsupported text-sm text-muted",
7336
7404
  children: "The json-render renderer is not installed: add @json-render/core and @json-render/react to this host."
7337
- });
7338
- if (!module) return null;
7339
- return /* @__PURE__ */ jsx(CatalogSurfaceProvider, {
7405
+ })] });
7406
+ if (!module) return rejection;
7407
+ return /* @__PURE__ */ jsxs(CatalogSurfaceProvider, {
7340
7408
  surfaceId,
7341
- spec,
7409
+ spec: sanitized.node ?? spec,
7342
7410
  actions: actions ?? [],
7343
7411
  ...onAction ? { onAction } : {},
7344
- children: /* @__PURE__ */ jsx(JsonRenderBody, {
7345
- spec,
7346
- module
7347
- })
7412
+ children: [
7413
+ rejection,
7414
+ sanitized.node ? /* @__PURE__ */ jsx(JsonRenderBody, {
7415
+ spec: sanitized.node,
7416
+ module
7417
+ }) : null,
7418
+ /* @__PURE__ */ jsx(SurfaceSimplifiedNote, { degradations: sanitized.degradations })
7419
+ ]
7348
7420
  });
7349
7421
  }
7350
7422
  /** registry 的 action 出口绑定到本 surface:json-render 派发的动作与组件内点击回传同一份载荷 */
@@ -7518,7 +7590,7 @@ function OpenUiSpecSurface({ spec, surfaceId, actions, onAction }) {
7518
7590
  const [unavailable, setUnavailable] = useState(false);
7519
7591
  useEffect(() => {
7520
7592
  let cancelled = false;
7521
- import("./openUiLibrary-Bdrji9qK-D2LxmM-a.js").then((loaded) => {
7593
+ import("./openUiLibrary-DURlAxjk-Do_yqg3u.js").then((loaded) => {
7522
7594
  if (!cancelled) setModule(loaded);
7523
7595
  }).catch(() => {
7524
7596
  if (!cancelled) setUnavailable(true);
@@ -7527,34 +7599,34 @@ function OpenUiSpecSurface({ spec, surfaceId, actions, onAction }) {
7527
7599
  cancelled = true;
7528
7600
  };
7529
7601
  }, []);
7530
- const validation = uiCatalog.validate(spec);
7531
- if (!validation.ok) return /* @__PURE__ */ jsxs("div", {
7532
- role: "alert",
7533
- className: "webskill-surface--error text-sm text-destructive",
7534
- children: ["Invalid UI spec: ", validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ")]
7535
- });
7536
- if (unavailable) return /* @__PURE__ */ jsx("div", {
7602
+ const sanitized = useSanitizedSpec(spec);
7603
+ const rejection = /* @__PURE__ */ jsx(SurfaceRejectionAlert, { degradations: sanitized.degradations });
7604
+ if (unavailable) return /* @__PURE__ */ jsxs(Fragment$1, { children: [rejection, /* @__PURE__ */ jsx("div", {
7537
7605
  role: "alert",
7538
7606
  className: "webskill-surface--unsupported text-sm text-muted",
7539
7607
  children: "The OpenUI renderer is not installed: add @openuidev/react-lang to this host."
7540
- });
7541
- if (!module) return null;
7608
+ })] });
7609
+ if (!module) return rejection;
7542
7610
  const { Renderer, webskillOpenUiLibrary } = module;
7543
7611
  return /* @__PURE__ */ jsx(CatalogSurfaceProvider, {
7544
7612
  surfaceId,
7545
- spec,
7613
+ spec: sanitized.node ?? spec,
7546
7614
  actions: actions ?? [],
7547
7615
  ...onAction ? { onAction } : {},
7548
- children: /* @__PURE__ */ jsx("div", {
7616
+ children: /* @__PURE__ */ jsxs("div", {
7549
7617
  className: "webskill-surface webskill-surface--spec",
7550
7618
  "data-testid": "openui-spec-surface",
7551
- children: /* @__PURE__ */ jsx(Renderer, {
7552
- response: toOpenUiSpecLang(spec),
7553
- library: webskillOpenUiLibrary
7554
- })
7619
+ children: [
7620
+ sanitized.node ? /* @__PURE__ */ jsx(Renderer, {
7621
+ response: toOpenUiSpecLang(sanitized.node),
7622
+ library: webskillOpenUiLibrary
7623
+ }) : null,
7624
+ rejection,
7625
+ /* @__PURE__ */ jsx(SurfaceSimplifiedNote, { degradations: sanitized.degradations })
7626
+ ]
7555
7627
  })
7556
7628
  });
7557
7629
  }
7558
7630
 
7559
7631
  //#endregion
7560
- export { InteractionForm, JsonRenderSpecSurface, NATIVE_SPEC_COMPONENTS, NativeSpecSurface, OpenUiSpecSurface, ReactBridgeState, ResultBlocks, SpecInteractionChannel, StreamingText, SurfaceRegistry, UiSurfaceList, UiSurfaceSnapshotList, UiSurfaceStore, catalogComponentImpls, createJsonRenderRegistry, probeJsonRenderAvailability };
7632
+ export { InteractionForm, JsonRenderSpecSurface, NATIVE_SPEC_COMPONENTS, NativeSpecSurface, OpenUiSpecSurface, ReactBridgeState, ResultBlocks, SpecInteractionChannel, StreamingText, SurfaceFormTextsProvider, SurfaceRegistry, UiSurfaceList, UiSurfaceSnapshotList, UiSurfaceStore, catalogComponentImpls, createJsonRenderRegistry, probeJsonRenderAvailability, useSurfaceFormTexts };
package/dist/ui-vue.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as InteractionResponse, s as InteractionRequest, x as UiBridge, y as RenderResultRequest } from "./types-CcxRLdJG-DCXyw1US.js";
1
+ import { c as InteractionResponse, s as InteractionRequest, x as UiBridge, y as RenderResultRequest } from "./types-B3n0cMZu-BDhheIhX.js";
2
2
  import { PropType } from "vue";
3
3
  //#region ../ui-vue/dist/index.d.ts
4
4
  //#region src/bridgeState.d.ts
package/dist/ui-vue.js CHANGED
@@ -1,4 +1,4 @@
1
- import { I as shapeInteractionValue, O as interactionToFormModel, P as renderMiniChart, g as applySuggestion, tt as renderMiniMarkdown, x as collectValues } from "./dist-DnYG2-eY.js";
1
+ import { R as renderMiniChart, Z as DEFAULT_SURFACE_FORM_TEXTS, ct as renderMiniMarkdown, dt as shapeInteractionValue, ot as interactionToFormModel, w as collectValues, y as applySuggestion } from "./dist-BQe1uglQ.js";
2
2
  import { defineComponent, h, reactive, ref } from "vue";
3
3
 
4
4
  //#region ../ui-vue/dist/index.js
@@ -164,7 +164,7 @@ const InteractionForm = defineComponent({
164
164
  id: `webskill-error-${control.name}`,
165
165
  role: "alert",
166
166
  class: "webskill-form__error"
167
- }, "This field is required") : null
167
+ }, DEFAULT_SURFACE_FORM_TEXTS.required) : null
168
168
  ])),
169
169
  h("div", { class: "webskill-form__actions" }, [h("button", {
170
170
  type: "submit",
package/dist/ui.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { gt as UiSpecNode } from "./types-CcxRLdJG-DCXyw1US.js";
2
- import { mn as buildRenderResult } from "./index-DkbABR43.js";
3
- import { $ as buildA2uiCatalogDefinition, A as UiActionDef, At as uiCatalog, B as UiSpecValidation, C as OpenUiRendererProps, Ct as shapeInteractionValue, D as UI_CATALOG_PROMPT_BUDGET_BYTES, Dt as toOpenUiSpecLang, E as UI_CATALOG_GROUPS, Et as toJsonRenderSpec, F as UiComponentDef, G as WEBSKILL_A2UI_CATALOG_ID, H as VERCEL_INTERACTION_TOOL_NAME, I as UiFormScope, J as WebFormBridge, K as WEBSKILL_STYLES_CSS, L as UiPreset, M as UiCatalogInput, N as UiCatalogPromptOptions, O as UI_PRESETS, Ot as toUiSurfaceActionDispatch, P as UiCatalogToolSourceOptions, Q as applySuggestion, R as UiPresetName, S as LoadedOpenUiPeers, St as renderRenderResult, T as RENDER_UI_TOOL, Tt as toA2uiSurfaceAction, U as VercelToolInvocation, V as UiSurfaceActionDispatch, W as VercelUiBridge, X as a2uiComponentSchema, Y as ZodRuntime, Z as a2uiComponentShapes, _ as DESCRIBE_UI_PRESET_TOOL, _t as mountEchart, a as A2UI_SURFACE_ACTION, at as collectValues, b as InteractionSpecLabels, bt as renderMiniChart, c as A2uiCatalogDefinition, ct as ensureStyles, d as A2uiMessage, dt as fromUiSurfaceActionDispatch, et as chartSpecFromProps, f as A2uiSpecActionEvent, ft as fromVercelToolResult, g as ControlModel, gt as loadWebSkillLitCatalog, h as CollectedValues, ht as loadOpenUiPeers, i as A2UI_SPEC_FORM_PATH, it as collectSpecActions, j as UiCatalog, jt as uiPreset, k as UI_PRESET_NAMES, kt as toVercelToolInvocation, l as A2uiCatalogHandle, lt as fromA2uiSpecAction, m as CHART_PALETTE, mt as interactionToUiSpec, n as A2UI_COMMON_TYPES, nt as collectFormScopes, o as A2UI_VERSION, ot as createUiCatalogToolSource, p as A2uiSpecMessageOptions, pt as interactionToFormModel, q as WEBSKILL_SURFACE_ACTION, r as A2UI_SPEC_ACTION, rt as collectScopedValues, s as A2uiCatalogComponent, st as defineUiCatalog, t as A2UI_BASIC_CATALOG_ID, tt as chartToTable, u as A2uiComponentShape, ut as fromA2uiSurfaceAction, v as EchartHandle, vt as qualifyFieldName, w as OpenUiRuntime, wt as toA2uiSpecMessages, x as JsonRenderSpec, xt as renderMiniMarkdown, y as FormModel, yt as renderBlocks, z as UiSpecIssue } from "./index-BwsK9lGk.js";
4
- export { A2UI_BASIC_CATALOG_ID, A2UI_COMMON_TYPES, A2UI_SPEC_ACTION, A2UI_SPEC_FORM_PATH, A2UI_SURFACE_ACTION, A2UI_VERSION, type A2uiCatalogComponent, type A2uiCatalogDefinition, type A2uiCatalogHandle, type A2uiComponentShape, type A2uiMessage, type A2uiSpecActionEvent, type A2uiSpecMessageOptions, CHART_PALETTE, type CollectedValues, type ControlModel, DESCRIBE_UI_PRESET_TOOL, type EchartHandle, type FormModel, type InteractionSpecLabels, type JsonRenderSpec, type LoadedOpenUiPeers, type OpenUiRendererProps, type OpenUiRuntime, RENDER_UI_TOOL, UI_CATALOG_GROUPS, UI_CATALOG_PROMPT_BUDGET_BYTES, UI_PRESETS, UI_PRESET_NAMES, type UiActionDef, type UiCatalog, type UiCatalogInput, type UiCatalogPromptOptions, type UiCatalogToolSourceOptions, type UiComponentDef, type UiFormScope, type UiPreset, type UiPresetName, type UiSpecIssue, type UiSpecNode, type UiSpecValidation, type UiSurfaceActionDispatch, VERCEL_INTERACTION_TOOL_NAME, type VercelToolInvocation, VercelUiBridge, WEBSKILL_A2UI_CATALOG_ID, WEBSKILL_STYLES_CSS, WEBSKILL_SURFACE_ACTION, WebFormBridge, type ZodRuntime, a2uiComponentSchema, a2uiComponentShapes, applySuggestion, buildA2uiCatalogDefinition, buildRenderResult, chartSpecFromProps, chartToTable, collectFormScopes, collectScopedValues, collectSpecActions, collectValues, createUiCatalogToolSource, defineUiCatalog, ensureStyles, fromA2uiSpecAction, fromA2uiSurfaceAction, fromUiSurfaceActionDispatch, fromVercelToolResult, interactionToFormModel, interactionToUiSpec, loadOpenUiPeers, loadWebSkillLitCatalog, mountEchart, qualifyFieldName, renderBlocks, renderMiniChart, renderMiniMarkdown, renderRenderResult, shapeInteractionValue, toA2uiSpecMessages, toA2uiSurfaceAction, toJsonRenderSpec, toOpenUiSpecLang, toUiSurfaceActionDispatch, toVercelToolInvocation, uiCatalog, uiPreset };
1
+ import { yt as UiSpecNode } from "./types-B3n0cMZu-BDhheIhX.js";
2
+ import { vn as buildRenderResult } from "./index-znZjobkr.js";
3
+ import { $ as UiSpecIssue, A as MAX_CONDITION_DEPTH, At as interactionToUiSpec, B as UI_CATALOG_PROMPT_BUDGET_BYTES, Bt as resolveColumnWidths, C as FieldCondition, Ct as ensureStyles, D as InteractionTexts, Dt as fromUiSurfaceActionDispatch, E as InteractionSpecLabels, Et as fromA2uiSurfaceAction, F as SPEC_TABLE_MIN_COLUMN_VAR, Ft as qualifyFieldName, G as UiCatalogInput, Gt as toA2uiSurfaceAction, H as UI_PRESET_NAMES, Ht as resolveSurfaceFormTexts, I as SPEC_TABLE_MIN_COLUMN_WIDTH, It as renderBlocks, J as UiComponentDef, Jt as toUiSurfaceActionDispatch, K as UiCatalogPromptOptions, Kt as toJsonRenderSpec, L as SpecColumnMeta, Lt as renderMiniChart, M as OpenUiRendererProps, Mt as loadWebSkillLitCatalog, N as OpenUiRuntime, Nt as mountEchart, O as JsonRenderSpec, Ot as fromVercelToolResult, P as RENDER_UI_TOOL, Pt as normalizeColumnWidths, Q as UiSpecDegradation, R as SurfaceFormTexts, Rt as renderMiniMarkdown, S as EvaluateFieldConditionOptions, St as defineUiCatalog, T as FormModel, Tt as fromA2uiSpecAction, U as UiActionDef, Ut as shapeInteractionValue, V as UI_PRESETS, Vt as resolveInteractionTexts, W as UiCatalog, Wt as toA2uiSpecMessages, X as UiPreset, Xt as uiCatalog, Y as UiFormScope, Yt as toVercelToolInvocation, Z as UiPresetName, Zt as uiPreset, _ as ControlModel, _t as collectFormScopes, a as A2UI_SURFACE_ACTION, at as VercelUiBridge, b as DESCRIBE_UI_PRESET_TOOL, bt as collectValues, c as A2uiCatalogDefinition, ct as WEBSKILL_SURFACE_ACTION, d as A2uiMessage, dt as a2uiComponentSchema, et as UiSpecSanitization, f as A2uiSpecActionEvent, ft as a2uiComponentShapes, g as ColumnWidthsRejection, gt as chartToTable, h as CollectedValues, ht as chartSpecFromProps, i as A2UI_SPEC_FORM_PATH, it as VercelToolInvocation, j as NormalizedColumnWidths, jt as loadOpenUiPeers, k as LoadedOpenUiPeers, kt as interactionToFormModel, l as A2uiCatalogHandle, lt as WebFormBridge, m as CHART_PALETTE, mt as buildA2uiCatalogDefinition, n as A2UI_COMMON_TYPES, nt as UiSurfaceActionDispatch, o as A2UI_VERSION, ot as WEBSKILL_A2UI_CATALOG_ID, p as A2uiSpecMessageOptions, pt as applySuggestion, q as UiCatalogToolSourceOptions, qt as toOpenUiSpecLang, r as A2UI_SPEC_ACTION, rt as VERCEL_INTERACTION_TOOL_NAME, s as A2uiCatalogComponent, st as WEBSKILL_STYLES_CSS, t as A2UI_BASIC_CATALOG_ID, tt as UiSpecValidation, u as A2uiComponentShape, ut as ZodRuntime, v as DEFAULT_INTERACTION_TEXTS, vt as collectScopedValues, w as FieldConditionResult, wt as evaluateFieldCondition, x as EchartHandle, xt as createUiCatalogToolSource, y as DEFAULT_SURFACE_FORM_TEXTS, yt as collectSpecActions, z as UI_CATALOG_GROUPS, zt as renderRenderResult } from "./index-DXNTIa-6.js";
4
+ export { A2UI_BASIC_CATALOG_ID, A2UI_COMMON_TYPES, A2UI_SPEC_ACTION, A2UI_SPEC_FORM_PATH, A2UI_SURFACE_ACTION, A2UI_VERSION, type A2uiCatalogComponent, type A2uiCatalogDefinition, type A2uiCatalogHandle, type A2uiComponentShape, type A2uiMessage, type A2uiSpecActionEvent, type A2uiSpecMessageOptions, CHART_PALETTE, type CollectedValues, type ColumnWidthsRejection, type ControlModel, DEFAULT_INTERACTION_TEXTS, DEFAULT_SURFACE_FORM_TEXTS, DESCRIBE_UI_PRESET_TOOL, type EchartHandle, type EvaluateFieldConditionOptions, type FieldCondition, type FieldConditionResult, type FormModel, type InteractionSpecLabels, type InteractionTexts, type JsonRenderSpec, type LoadedOpenUiPeers, MAX_CONDITION_DEPTH, type NormalizedColumnWidths, type OpenUiRendererProps, type OpenUiRuntime, RENDER_UI_TOOL, SPEC_TABLE_MIN_COLUMN_VAR, SPEC_TABLE_MIN_COLUMN_WIDTH, type SpecColumnMeta, type SurfaceFormTexts, UI_CATALOG_GROUPS, UI_CATALOG_PROMPT_BUDGET_BYTES, UI_PRESETS, UI_PRESET_NAMES, type UiActionDef, type UiCatalog, type UiCatalogInput, type UiCatalogPromptOptions, type UiCatalogToolSourceOptions, type UiComponentDef, type UiFormScope, type UiPreset, type UiPresetName, type UiSpecDegradation, type UiSpecIssue, type UiSpecNode, type UiSpecSanitization, type UiSpecValidation, type UiSurfaceActionDispatch, VERCEL_INTERACTION_TOOL_NAME, type VercelToolInvocation, VercelUiBridge, WEBSKILL_A2UI_CATALOG_ID, WEBSKILL_STYLES_CSS, WEBSKILL_SURFACE_ACTION, WebFormBridge, type ZodRuntime, a2uiComponentSchema, a2uiComponentShapes, applySuggestion, buildA2uiCatalogDefinition, buildRenderResult, chartSpecFromProps, chartToTable, collectFormScopes, collectScopedValues, collectSpecActions, collectValues, createUiCatalogToolSource, defineUiCatalog, ensureStyles, evaluateFieldCondition, fromA2uiSpecAction, fromA2uiSurfaceAction, fromUiSurfaceActionDispatch, fromVercelToolResult, interactionToFormModel, interactionToUiSpec, loadOpenUiPeers, loadWebSkillLitCatalog, mountEchart, normalizeColumnWidths, qualifyFieldName, renderBlocks, renderMiniChart, renderMiniMarkdown, renderRenderResult, resolveColumnWidths, resolveInteractionTexts, resolveSurfaceFormTexts, shapeInteractionValue, toA2uiSpecMessages, toA2uiSurfaceAction, toJsonRenderSpec, toOpenUiSpecLang, toUiSurfaceActionDispatch, toVercelToolInvocation, uiCatalog, uiPreset };