@webskill/sdk 0.4.0 → 0.6.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 +2 -0
  2. package/dist/agent.js +909 -0
  3. package/dist/browser.d.ts +233 -4
  4. package/dist/browser.js +869 -19
  5. package/dist/{catalogComponents-KsujmL4b-Clx1kCnU.js → catalogComponents-Dr5dFMAb-Dacibl1e.js} +372 -126
  6. package/dist/{dist-D9Lcn5Pp.js → dist-DnYG2-eY.js} +642 -39
  7. package/dist/{dist-C-Sh0MDU.js → dist-DusANsrn.js} +1035 -99
  8. package/dist/{env--jJB-TSX-04klhTYi.js → env-8cY40DXB-CGnEVZby.js} +7 -6
  9. package/dist/{env-BPUBZCwJ-4jat_SVG.d.ts → env-AK3cSMEA-Dli6QU5E.d.ts} +4 -3
  10. package/dist/governance.d.ts +46 -4
  11. package/dist/governance.js +45 -2
  12. package/dist/{index-CHXxDccV.d.ts → index-BMocOEi0.d.ts} +106 -10
  13. package/dist/index-BuTpBMzr.d.ts +474 -0
  14. package/dist/{index-DLfR2Y6I.d.ts → index-C-KFAZoF.d.ts} +337 -18
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +3 -3
  17. package/dist/mcp.d.ts +39 -8
  18. package/dist/mcp.js +53 -19
  19. package/dist/{memoryArtifactStore-BtOeB_hm-tj3fC5ip.js → memoryArtifactStore-52Zn9npI-BMPYwvoy.js} +10 -2
  20. package/dist/node.d.ts +4 -4
  21. package/dist/node.js +9 -2
  22. package/dist/{openUiLibrary-YLS-cxyT-C96jWDQq.js → openUiLibrary-Bdrji9qK-DzAxRlTY.js} +3 -3
  23. package/dist/{skillVersionStore-uyefLPR1-DXOzbksv.d.ts → skillVersionStore-BzLbzFOL-CxdAFWO2.d.ts} +4 -3
  24. package/dist/{testing-DDCJWvgA.js → testing-CYTFqkDm.js} +1 -1
  25. package/dist/testing.d.ts +2 -2
  26. package/dist/testing.js +3 -3
  27. package/dist/{types-7Wcg--Vh-1YlQ4jF9.d.ts → types-4pg-qp_I-Gq63X8Oa.d.ts} +55 -5
  28. package/dist/ui-react.d.ts +26 -5
  29. package/dist/ui-react.js +147 -29
  30. package/dist/ui-vue.d.ts +1 -1
  31. package/dist/ui-vue.js +30 -6
  32. package/dist/ui.d.ts +4 -4
  33. package/dist/ui.js +3 -3
  34. package/dist/{webskillLitCatalog-CSTbhBe_-CYIs5BX8.js → webskillLitCatalog-_mugzRHx-B_54vxum.js} +88 -2
  35. package/package.json +6 -1
@@ -1,10 +1,10 @@
1
1
  import { a as __require, i as __reExport, n as __esmMin, o as __toCommonJS, r as __exportAll$2, s as __toESM$1, t as __commonJSMin$1 } from "./rolldown-runtime-BOF7iYI8.js";
2
2
  import { m as WebSkillError } from "./dist-8oQRa8Xz.js";
3
- import { G as mountEchart, U as chartSpecFromProps } from "./dist-D9Lcn5Pp.js";
3
+ import { M as qualifyFieldName, Q as chartSpecFromProps, et as mountEchart, v as collectFormScopes, y as collectScopedValues } from "./dist-DnYG2-eY.js";
4
4
  import minpath$1 from "node:path";
5
5
  import { fileURLToPath as urlToPath$1 } from "node:url";
6
6
  import * as React$10 from "react";
7
- import React, { Fragment, createContext, createElement, forwardRef, memo, useCallback, useContext, useDeferredValue, useEffect, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState, default as react_default } from "react";
7
+ import React, { Fragment, createContext, createElement, forwardRef, memo, useCallback, useContext, useDeferredValue, useEffect, useId, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState, default as react_default } from "react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  import * as ReactDOM from "react-dom";
10
10
  import minproc$1 from "node:process";
@@ -3407,11 +3407,49 @@ const getDefaultConfig = () => {
3407
3407
  const twMerge = /*#__PURE__*/ createTailwindMerge(getDefaultConfig);
3408
3408
 
3409
3409
  //#endregion
3410
- //#region ../ui-kit/dist/cn-Dt6Yi1Qv.js
3410
+ //#region ../ui-kit/dist/useDarkAncestor-D41bzGNA.js
3411
3411
  /** shadcn 约定的类名合并:后写的 Tailwind 类覆盖先写的同族类。 */
3412
3412
  function cn(...inputs) {
3413
3413
  return twMerge(clsx(inputs));
3414
3414
  }
3415
+ /**
3416
+ * 声明了主题的祖先:`data-theme` 由 ThemeScope 挂(亮暗都挂),`.dark` 是宿主页面惯用的暗色类名。
3417
+ * 两者一起选,`closest` 才会停在**最近**的那一层,而不是越过亮色实例去命中外层的暗色宿主。
3418
+ */
3419
+ const THEME_ANCESTOR = "[data-theme], .dark";
3420
+ /**
3421
+ * 判定挂载点**最近的**主题祖先是否处于暗色(0.6.0 FR-20.4)。
3422
+ *
3423
+ * 不用 `document.querySelector('.dark')`:那是全局查询,宿主页面是暗色时,
3424
+ * 嵌在暗色宿主里的亮色 SDK 实例也会被判成暗色(反之亦然)。
3425
+ *
3426
+ * 返回 ref 回调而不是接受 ref 对象:ref 对象的赋值不触发渲染,拿不到「已挂载」这个时机。
3427
+ */
3428
+ function useDarkAncestor() {
3429
+ const [node, setNode] = useState(null);
3430
+ const [dark, setDark] = useState(false);
3431
+ useEffect(() => {
3432
+ if (!node) return;
3433
+ const update = () => {
3434
+ const scope = node.closest(THEME_ANCESTOR);
3435
+ if (!scope) {
3436
+ setDark(false);
3437
+ return;
3438
+ }
3439
+ const declared = scope.getAttribute("data-theme");
3440
+ setDark(declared === null ? true : declared === "dark");
3441
+ };
3442
+ update();
3443
+ const observer = new MutationObserver(update);
3444
+ observer.observe(document.documentElement, {
3445
+ attributes: true,
3446
+ attributeFilter: ["class", "data-theme"],
3447
+ subtree: true
3448
+ });
3449
+ return () => observer.disconnect();
3450
+ }, [node]);
3451
+ return [dark, setNode];
3452
+ }
3415
3453
 
3416
3454
  //#endregion
3417
3455
  //#region ../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.5_@types+react@19.2.17_react@19.2.8/node_modules/@radix-ui/react-compose-refs/dist/index.mjs
@@ -5551,14 +5589,14 @@ var __name$10 = (target, value) => __defProp$12(target, "name", {
5551
5589
  });
5552
5590
  var useReactId = React$10[" useId ".trim().toString()] || (() => void 0);
5553
5591
  var count = 0;
5554
- function useId(deterministicId) {
5592
+ function useId$1(deterministicId) {
5555
5593
  const [id, setId] = React$10.useState(useReactId());
5556
5594
  useLayoutEffect2(() => {
5557
5595
  if (!deterministicId) setId((reactId) => reactId ?? String(count++));
5558
5596
  }, [deterministicId]);
5559
5597
  return deterministicId || (id ? `radix-${id}` : "");
5560
5598
  }
5561
- __name$10(useId, "useId");
5599
+ __name$10(useId$1, "useId");
5562
5600
 
5563
5601
  //#endregion
5564
5602
  //#region ../../node_modules/.pnpm/@floating-ui+utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
@@ -7564,7 +7602,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React$10.forwardRef(/* @__PURE__ */ _
7564
7602
  var ITEM_NAME$1 = "RovingFocusGroupItem";
7565
7603
  var RovingFocusGroupItem = /* @__PURE__ */ React$10.forwardRef(/* @__PURE__ */ __name$6(function RovingFocusGroupItem2(props, forwardedRef) {
7566
7604
  const { __scopeRovingFocusGroup, focusable = true, active = false, tabStopId, children, ...itemProps } = props;
7567
- const autoId = useId();
7605
+ const autoId = useId$1();
7568
7606
  const id = tabStopId || autoId;
7569
7607
  const context = useRovingFocusContext(ITEM_NAME$1, __scopeRovingFocusGroup);
7570
7608
  const isCurrentTabStop = context.currentTabStopId === id;
@@ -10241,9 +10279,9 @@ var DropdownMenu$1 = /* @__PURE__ */ __name$4((props) => {
10241
10279
  });
10242
10280
  return /* @__PURE__ */ jsx(DropdownMenuProvider, {
10243
10281
  scope: __scopeDropdownMenu,
10244
- triggerId: useId(),
10282
+ triggerId: useId$1(),
10245
10283
  triggerRef,
10246
- contentId: useId(),
10284
+ contentId: useId$1(),
10247
10285
  open,
10248
10286
  onOpenChange: setOpen,
10249
10287
  onOpenToggle: React$10.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
@@ -11157,9 +11195,9 @@ var Dialog = /* @__PURE__ */ __name((props) => {
11157
11195
  scope: __scopeDialog,
11158
11196
  triggerRef,
11159
11197
  contentRef,
11160
- contentId: useId(),
11161
- titleId: useId(),
11162
- descriptionId: useId(),
11198
+ contentId: useId$1(),
11199
+ titleId: useId$1(),
11200
+ descriptionId: useId$1(),
11163
11201
  titlePresent: titleCount > 0,
11164
11202
  descriptionPresent: descriptionCount > 0,
11165
11203
  setTitleCount,
@@ -11349,7 +11387,7 @@ var me = React$10.forwardRef((r, o) => {
11349
11387
  groups: /* @__PURE__ */ new Set()
11350
11388
  }
11351
11389
  };
11352
- }), u = L(() => /* @__PURE__ */ new Set()), c = L(() => /* @__PURE__ */ new Map()), d = L(() => /* @__PURE__ */ new Map()), f = L(() => /* @__PURE__ */ new Set()), p = pe(r), { label: b, children: m, value: R, onValueChange: x, filter: C, shouldFilter: S, loop: A, disablePointerSelection: ge = !1, vimBindings: j = !0, ...O } = r, $ = useId(), q = useId(), _ = useId(), I = React$10.useRef(null), v = ke();
11390
+ }), u = L(() => /* @__PURE__ */ new Set()), c = L(() => /* @__PURE__ */ new Map()), d = L(() => /* @__PURE__ */ new Map()), f = L(() => /* @__PURE__ */ new Set()), p = pe(r), { label: b, children: m, value: R, onValueChange: x, filter: C, shouldFilter: S, loop: A, disablePointerSelection: ge = !1, vimBindings: j = !0, ...O } = r, $ = useId$1(), q = useId$1(), _ = useId$1(), I = React$10.useRef(null), v = ke();
11353
11391
  k(() => {
11354
11392
  if (R !== void 0) {
11355
11393
  let e = R.trim();
@@ -11547,7 +11585,7 @@ var me = React$10.forwardRef((r, o) => {
11547
11585
  });
11548
11586
  var he = React$10.forwardRef((r, o) => {
11549
11587
  var _, I;
11550
- let n = useId(), u = React$10.useRef(null), c = React$10.useContext(fe), d = K(), f = pe(r), p = (I = (_ = f.current) == null ? void 0 : _.forceMount) != null ? I : c == null ? void 0 : c.forceMount;
11588
+ let n = useId$1(), u = React$10.useRef(null), c = React$10.useContext(fe), d = K(), f = pe(r), p = (I = (_ = f.current) == null ? void 0 : _.forceMount) != null ? I : c == null ? void 0 : c.forceMount;
11551
11589
  k(() => {
11552
11590
  if (!p) return d.item(n, c == null ? void 0 : c.id);
11553
11591
  }, [p]);
@@ -11588,7 +11626,7 @@ var he = React$10.forwardRef((r, o) => {
11588
11626
  }, r.children);
11589
11627
  });
11590
11628
  var Ee = React$10.forwardRef((r, o) => {
11591
- let { heading: n, children: u, forceMount: c, ...d } = r, f = useId(), p = React$10.useRef(null), b = React$10.useRef(null), m = useId(), R = K(), x = P((S) => c || R.filter() === !1 ? !0 : S.search ? S.filtered.groups.has(f) : !0);
11629
+ let { heading: n, children: u, forceMount: c, ...d } = r, f = useId$1(), p = React$10.useRef(null), b = React$10.useRef(null), m = useId$1(), R = K(), x = P((S) => c || R.filter() === !1 ? !0 : S.search ? S.filtered.groups.has(f) : !0);
11592
11630
  k(() => R.group(f), []), ve(f, p, [
11593
11631
  r.value,
11594
11632
  r.heading,
@@ -14886,7 +14924,7 @@ function checkRule(state) {
14886
14924
  * @param {Info} info
14887
14925
  * @returns {string}
14888
14926
  */
14889
- function list$4(node, parent, state, info) {
14927
+ function list$5(node, parent, state, info) {
14890
14928
  const exit = state.enter("list");
14891
14929
  const bulletCurrent = state.bulletCurrent;
14892
14930
  /** @type {string} */
@@ -15172,7 +15210,7 @@ const handle = {
15172
15210
  inlineCode: inlineCode$2,
15173
15211
  link: link$2,
15174
15212
  linkReference: linkReference$2,
15175
- list: list$4,
15213
+ list: list$5,
15176
15214
  listItem: listItem$2,
15177
15215
  paragraph: paragraph$2,
15178
15216
  root: root$4,
@@ -24087,7 +24125,7 @@ function tokenizeThematicBreak$1(effects, ok, nok) {
24087
24125
  * } from 'micromark-util-types'
24088
24126
  */
24089
24127
  /** @type {Construct} */
24090
- const list$3 = {
24128
+ const list$4 = {
24091
24129
  continuation: { tokenize: tokenizeListContinuation$1 },
24092
24130
  exit: tokenizeListEnd$1,
24093
24131
  name: "list",
@@ -24207,7 +24245,7 @@ function tokenizeListContinuation$1(effects, ok, nok) {
24207
24245
  function notInCurrentItem(code) {
24208
24246
  self.containerState._closeFlow = true;
24209
24247
  self.interrupt = void 0;
24210
- return factorySpace$1(effects, effects.attempt(list$3, ok, nok), "linePrefix", self.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code);
24248
+ return factorySpace$1(effects, effects.attempt(list$4, ok, nok), "linePrefix", self.parser.constructs.disable.null.includes("codeIndented") ? void 0 : 4)(code);
24211
24249
  }
24212
24250
  }
24213
24251
  /**
@@ -34368,19 +34406,19 @@ var constructs_exports$1 = /* @__PURE__ */ __exportAll$2({
34368
34406
  });
34369
34407
  /** @satisfies {Extension['document']} */
34370
34408
  const document$3 = {
34371
- [42]: list$3,
34372
- [43]: list$3,
34373
- [45]: list$3,
34374
- [48]: list$3,
34375
- [49]: list$3,
34376
- [50]: list$3,
34377
- [51]: list$3,
34378
- [52]: list$3,
34379
- [53]: list$3,
34380
- [54]: list$3,
34381
- [55]: list$3,
34382
- [56]: list$3,
34383
- [57]: list$3,
34409
+ [42]: list$4,
34410
+ [43]: list$4,
34411
+ [45]: list$4,
34412
+ [48]: list$4,
34413
+ [49]: list$4,
34414
+ [50]: list$4,
34415
+ [51]: list$4,
34416
+ [52]: list$4,
34417
+ [53]: list$4,
34418
+ [54]: list$4,
34419
+ [55]: list$4,
34420
+ [56]: list$4,
34421
+ [57]: list$4,
34384
34422
  [62]: blockQuote$1
34385
34423
  };
34386
34424
  /** @satisfies {Extension['contentInitial']} */
@@ -36686,7 +36724,7 @@ function listItemLoose$1(node) {
36686
36724
  * @returns {Element}
36687
36725
  * hast node.
36688
36726
  */
36689
- function list$2(state, node) {
36727
+ function list$3(state, node) {
36690
36728
  /** @type {Properties} */
36691
36729
  const properties = {};
36692
36730
  const results = state.all(node);
@@ -37081,7 +37119,7 @@ const handlers$1 = {
37081
37119
  linkReference: linkReference$1,
37082
37120
  link: link$1,
37083
37121
  listItem: listItem$1,
37084
- list: list$2,
37122
+ list: list$3,
37085
37123
  paragraph: paragraph$1,
37086
37124
  root: root$2,
37087
37125
  strong: strong$1,
@@ -99560,6 +99598,19 @@ const PanelLeft = createLucideIcon("panel-left", [["rect", {
99560
99598
  * This source code is licensed under the ISC license.
99561
99599
  * See the LICENSE file in the root directory of this source tree.
99562
99600
  */
99601
+ const Plus = createLucideIcon("plus", [["path", {
99602
+ d: "M5 12h14",
99603
+ key: "1ays0h"
99604
+ }], ["path", {
99605
+ d: "M12 5v14",
99606
+ key: "s699le"
99607
+ }]]);
99608
+ /**
99609
+ * @license lucide-react v1.27.0 - ISC
99610
+ *
99611
+ * This source code is licensed under the ISC license.
99612
+ * See the LICENSE file in the root directory of this source tree.
99613
+ */
99563
99614
  const Search = createLucideIcon("search", [["path", {
99564
99615
  d: "m21 21-4.34-4.34",
99565
99616
  key: "14j7rj"
@@ -99672,6 +99723,26 @@ function Switch({ className = "", label, ...props }) {
99672
99723
  })]
99673
99724
  });
99674
99725
  }
99726
+ /**
99727
+ * 一个 SDK 实例的主题作用域(0.6.0 FR-20.4)。
99728
+ *
99729
+ * 解决两件事:
99730
+ * 1. Radix 的 Portal 默认渲染到 `document.body`,会逃出主题子树 —— 这里在作用域**内部**
99731
+ * 提供一个 Portal 容器,浮层因此仍处在带主题类名的祖先链下;
99732
+ * 2. 原生 `<select>` 的下拉由浏览器按 `color-scheme` 绘制,类名管不到 —— 容器上的
99733
+ * `data-webskill-theme` 属性在 base.css 里显式声明了 `color-scheme`。
99734
+ *
99735
+ * 宿主页面自身的类名不被改动:作用域只作用于自己的子树。
99736
+ */
99737
+ const PortalContainerContext = createContext(void 0);
99738
+ /**
99739
+ * 当前实例的 Portal 容器;不在 `ThemeScope` 内时返回 `undefined`,
99740
+ * 调用方据此回落到 Radix 默认的 `document.body`。
99741
+ * @experimental
99742
+ */
99743
+ function usePortalContainer() {
99744
+ return useContext(PortalContainerContext);
99745
+ }
99675
99746
  const DropdownMenu = Root2;
99676
99747
  function DropdownMenuTrigger({ children, className = "", asChild, ...props }) {
99677
99748
  const triggerClass = asChild ? className : `inline-flex h-9 items-center justify-center rounded-md border border-border bg-surface px-3 text-sm font-medium text-ink shadow-xs outline-none transition-colors hover:bg-subtle focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20 ${className}`;
@@ -99683,12 +99754,15 @@ function DropdownMenuTrigger({ children, className = "", asChild, ...props }) {
99683
99754
  });
99684
99755
  }
99685
99756
  function DropdownMenuContent({ children, className = "", sideOffset = 6, ...props }) {
99686
- return /* @__PURE__ */ jsx(Portal2, { children: /* @__PURE__ */ jsx(Content2, {
99687
- sideOffset,
99688
- className: `z-50 min-w-40 rounded-md border border-border bg-surface p-1 text-sm text-ink shadow-pop outline-none ${className}`,
99689
- ...props,
99690
- children
99691
- }) });
99757
+ return /* @__PURE__ */ jsx(Portal2, {
99758
+ container: usePortalContainer(),
99759
+ children: /* @__PURE__ */ jsx(Content2, {
99760
+ sideOffset,
99761
+ className: `z-50 min-w-40 rounded-md border border-border bg-surface p-1 text-sm text-ink shadow-pop outline-none ${className}`,
99762
+ ...props,
99763
+ children
99764
+ })
99765
+ });
99692
99766
  }
99693
99767
  function DropdownMenuCheckboxItem({ children, className = "", ...props }) {
99694
99768
  return /* @__PURE__ */ jsxs(CheckboxItem2, {
@@ -99762,7 +99836,6 @@ function DataTable({ children, className = "", containerClassName = "", ...props
99762
99836
  }
99763
99837
  const toneClasses$1 = {
99764
99838
  neutral: "bg-subtle text-muted",
99765
- primary: "bg-subtle text-ink",
99766
99839
  success: "bg-success-soft text-success",
99767
99840
  warning: "bg-warning-soft text-warning",
99768
99841
  info: "bg-info-soft text-info",
@@ -111452,7 +111525,7 @@ function listItemLoose(node) {
111452
111525
  * @returns {Element}
111453
111526
  * hast node.
111454
111527
  */
111455
- function list(state, node) {
111528
+ function list$2(state, node) {
111456
111529
  /** @type {Properties} */
111457
111530
  const properties = {};
111458
111531
  const results = state.all(node);
@@ -111817,7 +111890,7 @@ const handlers = {
111817
111890
  linkReference,
111818
111891
  link,
111819
111892
  listItem,
111820
- list,
111893
+ list: list$2,
111821
111894
  paragraph,
111822
111895
  root,
111823
111896
  strong,
@@ -119890,29 +119963,11 @@ function resolveLanguage(raw) {
119890
119963
  if (raw in languages) return raw;
119891
119964
  return languageAliases[raw];
119892
119965
  }
119893
- /** 探测 .dark 祖先(class 策略):监听 documentElement/body 的 class 变化 */
119894
- function useDarkClass() {
119895
- const [dark, setDark] = useState(() => typeof document !== "undefined" && document.querySelector(".dark") !== null);
119896
- useEffect(() => {
119897
- const update = () => setDark(document.querySelector(".dark") !== null);
119898
- const observer = new MutationObserver(update);
119899
- observer.observe(document.documentElement, {
119900
- attributes: true,
119901
- attributeFilter: ["class"]
119902
- });
119903
- if (document.body) observer.observe(document.body, {
119904
- attributes: true,
119905
- attributeFilter: ["class"]
119906
- });
119907
- update();
119908
- return () => observer.disconnect();
119909
- }, []);
119910
- return dark;
119911
- }
119912
119966
  function CodeBlock({ node: _node, className, children, ...rest }) {
119913
- const dark = useDarkClass();
119967
+ const [dark, themeRef] = useDarkAncestor();
119914
119968
  const language = resolveLanguage(/language-(\w+)/.exec(className ?? "")?.[1]);
119915
119969
  if (language) return /* @__PURE__ */ jsxs("div", {
119970
+ ref: themeRef,
119916
119971
  className: "my-3 overflow-hidden rounded-card border border-border",
119917
119972
  children: [/* @__PURE__ */ jsx("div", {
119918
119973
  className: "border-b border-border bg-subtle px-3 py-1.5 font-mono text-xs text-muted",
@@ -120085,9 +120140,27 @@ const MarkdownText = memo(function MarkdownText({ className }) {
120085
120140
  defer: true
120086
120141
  });
120087
120142
  });
120143
+ /**
120144
+ * provider 相关的默认值与切换规则(0.6.0 FR-13.1)。
120145
+ * chatbot 设置面板与 console 的 `connections.models` 共用这一份——
120146
+ * 0.5.x 时两处各自硬编码,改一处漏一处。
120147
+ */
120148
+ /**
120149
+ * 各 provider 的官方默认端点。取值必须与客户端内部的 fallback 一致(T-03-2 断言):
120150
+ * 客户端的 fallback 保证「用户没填也能跑」,这张表只服务 UI 预填,两者说的是同一件事。
120151
+ * `openai-compatible` 与 `chrome-builtin` 无默认——前者端点任意,后者根本不走 HTTP。
120152
+ * @experimental
120153
+ */
120154
+ const PROVIDER_DEFAULT_BASE_URL = {
120155
+ "openai-compatible": void 0,
120156
+ anthropic: "https://api.anthropic.com",
120157
+ google: "https://generativelanguage.googleapis.com",
120158
+ "chrome-builtin": void 0
120159
+ };
120160
+ const KNOWN_DEFAULT_BASE_URLS = new Set(Object.values(PROVIDER_DEFAULT_BASE_URL).filter((url) => url !== void 0));
120088
120161
 
120089
120162
  //#endregion
120090
- //#region ../ui-react/dist/catalogComponents-KsujmL4b.js
120163
+ //#region ../ui-react/dist/catalogComponents-Dr5dFMAb.js
120091
120164
  /** echarts 挂载点:surface 图表与 catalog 声明树的 Chart 节点共用,实现在 `@webskill/ui`,与 A2UI 档同一份 */
120092
120165
  function EChart({ chart }) {
120093
120166
  const containerRef = useRef(null);
@@ -120125,19 +120198,53 @@ function useSurfaceForm({ surfaceId, spec, actions, runId, draft, onAction, onDr
120125
120198
  collectFields(spec, out);
120126
120199
  return out;
120127
120200
  }, [spec]);
120201
+ const scopes = useMemo(() => collectFormScopes(spec), [spec]);
120202
+ const scoping = scopes.length > 1;
120203
+ const scopeFields = useMemo(() => new Map(scopes.map((scope) => {
120204
+ const out = [];
120205
+ collectFields(scope.form, out);
120206
+ return [scope.scopeId, out];
120207
+ })), [scopes]);
120208
+ const nodeScopes = useMemo(() => new Map(scopes.map((scope) => [scope.form, scope])), [scopes]);
120209
+ const defaults = useMemo(() => {
120210
+ const out = {};
120211
+ const add = (field, scopeId) => {
120212
+ if (field["defaultValue"] !== void 0) out[qualifyFieldName(String(field["name"]), scopeId)] = field["defaultValue"];
120213
+ };
120214
+ if (!scoping) {
120215
+ for (const field of fields) add(field);
120216
+ return out;
120217
+ }
120218
+ for (const scope of scopes) for (const field of scopeFields.get(scope.scopeId) ?? []) add(field, scope.scopeId);
120219
+ return out;
120220
+ }, [
120221
+ fields,
120222
+ scopes,
120223
+ scopeFields,
120224
+ scoping
120225
+ ]);
120226
+ const claims = useRef({
120227
+ spec,
120228
+ map: /* @__PURE__ */ new Map()
120229
+ });
120230
+ if (claims.current.spec !== spec) claims.current = {
120231
+ spec,
120232
+ map: /* @__PURE__ */ new Map()
120233
+ };
120128
120234
  const values = {
120129
- ...useMemo(() => Object.fromEntries(fields.filter((field) => field["defaultValue"] !== void 0).map((field) => [String(field["name"]), field["defaultValue"]])), [fields]),
120235
+ ...defaults,
120130
120236
  ...touched
120131
120237
  };
120132
120238
  const resolveActionId = (intent, nodeId) => nodeId ?? actions.find((action) => action.intent === intent)?.id ?? intent;
120133
- const dispatch = (actionId, withValues) => {
120239
+ const dispatch = (actionId, withValues, scope) => {
120134
120240
  const declared = actions.find((action) => action.id === actionId);
120135
120241
  onAction?.({
120136
120242
  surfaceId,
120137
120243
  actionId,
120138
120244
  intent: declared?.intent ?? "select",
120139
120245
  ...declared?.nonce ? { nonce: declared.nonce } : {},
120140
- ...withValues ? { value: { ...values } } : {}
120246
+ ...scope ? { scopeId: scope.scopeId } : {},
120247
+ ...withValues ? { value: collectScopedValues(values, scope) } : {}
120141
120248
  });
120142
120249
  };
120143
120250
  return {
@@ -120145,45 +120252,63 @@ function useSurfaceForm({ surfaceId, spec, actions, runId, draft, onAction, onDr
120145
120252
  actions,
120146
120253
  values,
120147
120254
  errors,
120255
+ scopes,
120148
120256
  resolveActionId,
120149
- setValue: (name, value) => {
120257
+ scopeOfNode: (node) => scoping ? nodeScopes.get(node) : void 0,
120258
+ claimScope: (instanceId, formProps) => {
120259
+ if (!scoping) return void 0;
120260
+ const claimed = claims.current.map.get(instanceId);
120261
+ if (claimed) return claimed;
120262
+ const taken = new Set([...claims.current.map.values()].map((scope) => scope.scopeId));
120263
+ const match = scopes.find((scope) => !taken.has(scope.scopeId) && Object.entries(scope.form.props ?? {}).every(([key, value]) => value === formProps[key]));
120264
+ if (match) claims.current.map.set(instanceId, match);
120265
+ return match;
120266
+ },
120267
+ setValue: (key, value) => {
120150
120268
  const next = {
120151
120269
  ...touched,
120152
- [name]: value
120270
+ [key]: value
120153
120271
  };
120154
120272
  setTouched(next);
120155
- setErrors(({ [name]: _cleared, ...rest }) => rest);
120273
+ setErrors(({ [key]: _cleared, ...rest }) => rest);
120156
120274
  if (runId) onDraftChange?.({
120157
120275
  runId,
120158
120276
  surfaceId,
120159
120277
  value: next
120160
120278
  });
120161
120279
  },
120162
- emit: (actionId) => dispatch(actionId, false),
120163
- submit: (intent, nodeId) => {
120164
- const missing = fields.filter((field) => field["required"] === true && isBlank(values[String(field["name"])]));
120280
+ emit: (actionId, scope) => dispatch(actionId, false, scope),
120281
+ submit: (intent, nodeId, scope) => {
120282
+ const missing = (scope ? scopeFields.get(scope.scopeId) ?? [] : fields).filter((field) => field["required"] === true && isBlank(values[qualifyFieldName(String(field["name"]), scope?.scopeId)]));
120165
120283
  if (missing.length > 0) {
120166
- setErrors(Object.fromEntries(missing.map((field) => [String(field["name"]), REQUIRED_MESSAGE])));
120284
+ const flagged = Object.fromEntries(missing.map((field) => [qualifyFieldName(String(field["name"]), scope?.scopeId), REQUIRED_MESSAGE]));
120285
+ setErrors((prev) => ({
120286
+ ...scope ? withoutScope(prev, scope.scopeId) : {},
120287
+ ...flagged
120288
+ }));
120167
120289
  return;
120168
120290
  }
120169
- setErrors({});
120170
- dispatch(resolveActionId(intent, nodeId), true);
120291
+ setErrors((prev) => scope ? withoutScope(prev, scope.scopeId) : {});
120292
+ dispatch(scope && !nodeId ? scope.submitActionId : resolveActionId(intent, nodeId), true, scope);
120171
120293
  }
120172
120294
  };
120173
120295
  }
120296
+ const withoutScope = (errors, scopeId) => Object.fromEntries(Object.entries(errors).filter(([key]) => !key.startsWith(`${scopeId}.`)));
120174
120297
  /** catalog `Field` 的唯一控件实现:8 种 type 的取值语义在这里定死 */
120175
- function SurfaceField({ form, props }) {
120298
+ function SurfaceField({ form, props, scope }) {
120176
120299
  const name = str(props, "name");
120300
+ const key = qualifyFieldName(name, scope?.scopeId);
120177
120301
  const label = str(props, "label", name);
120178
120302
  const type = str(props, "type", "text");
120179
120303
  const required = props["required"] === true;
120180
- const value = form.values[name];
120181
- const error = form.errors[name];
120182
- const errorId = error ? `webskill-surface-${form.surfaceId}-${name}-error` : void 0;
120304
+ const value = form.values[key];
120305
+ const error = form.errors[key];
120306
+ const errorId = error ? `webskill-surface-${form.surfaceId}-${key}-error` : void 0;
120183
120307
  const options = Array.isArray(props["options"]) ? props["options"] : [];
120308
+ const suggestion = props["suggestion"];
120184
120309
  /** 控件的机器可读锚点:宿主与测试据此定位字段,不依赖标签文案 */
120185
120310
  const anchor = {
120186
- "data-webskill-surface-control": name,
120311
+ "data-webskill-surface-control": key,
120187
120312
  ...error ? {
120188
120313
  "aria-invalid": true,
120189
120314
  "aria-describedby": errorId
@@ -120191,17 +120316,17 @@ function SurfaceField({ form, props }) {
120191
120316
  };
120192
120317
  const control = () => {
120193
120318
  if (type === "textarea") return /* @__PURE__ */ jsx(Textarea, {
120194
- id: name,
120319
+ id: key,
120195
120320
  ...anchor,
120196
120321
  invalid: Boolean(error),
120197
120322
  value: typeof value === "string" ? value : "",
120198
- onChange: (event) => form.setValue(name, event.target.value)
120323
+ onChange: (event) => form.setValue(key, event.target.value)
120199
120324
  });
120200
120325
  if (type === "toggle") return /* @__PURE__ */ jsx(Switch, {
120201
- id: name,
120326
+ id: key,
120202
120327
  ...anchor,
120203
120328
  checked: value === true,
120204
- onCheckedChange: (next) => form.setValue(name, next)
120329
+ onCheckedChange: (next) => form.setValue(key, next)
120205
120330
  });
120206
120331
  if (type === "select" || type === "multi-select") {
120207
120332
  const multiple = type === "multi-select";
@@ -120210,13 +120335,13 @@ function SurfaceField({ form, props }) {
120210
120335
  return index < 0 ? "" : String(index);
120211
120336
  };
120212
120337
  return /* @__PURE__ */ jsx("select", {
120213
- id: name,
120338
+ id: key,
120214
120339
  ...anchor,
120215
120340
  multiple,
120216
120341
  value: multiple ? Array.isArray(value) ? value.map(indexOf) : [] : indexOf(value),
120217
120342
  onChange: (event) => {
120218
120343
  const pick = (index) => options[Number(index)].value;
120219
- form.setValue(name, multiple ? [...event.target.selectedOptions].map((option) => pick(option.value)) : pick(event.target.value));
120344
+ form.setValue(key, multiple ? [...event.target.selectedOptions].map((option) => pick(option.value)) : pick(event.target.value));
120220
120345
  },
120221
120346
  children: options.map((option, index) => /* @__PURE__ */ jsx("option", {
120222
120347
  value: String(index),
@@ -120225,29 +120350,48 @@ function SurfaceField({ form, props }) {
120225
120350
  });
120226
120351
  }
120227
120352
  if (type === "file") return /* @__PURE__ */ jsx("input", {
120228
- id: name,
120353
+ id: key,
120229
120354
  ...anchor,
120230
120355
  type: "file",
120231
- onChange: (event) => form.setValue(name, event.target.files?.[0]?.name ?? "")
120356
+ onChange: (event) => form.setValue(key, event.target.files?.[0]?.name ?? "")
120232
120357
  });
120233
120358
  return /* @__PURE__ */ jsx(Input, {
120234
- id: name,
120359
+ id: key,
120235
120360
  ...anchor,
120236
120361
  invalid: Boolean(error),
120237
120362
  type: type === "number" ? "number" : type === "date" ? "date" : "text",
120238
120363
  value: typeof value === "string" || typeof value === "number" ? String(value) : "",
120239
- onChange: (event) => form.setValue(name, type === "number" ? Number(event.target.value) : event.target.value)
120364
+ onChange: (event) => form.setValue(key, type === "number" ? Number(event.target.value) : event.target.value)
120240
120365
  });
120241
120366
  };
120242
120367
  return /* @__PURE__ */ jsxs("label", {
120243
120368
  className: "flex flex-col gap-1 text-sm",
120244
- htmlFor: name,
120369
+ htmlFor: key,
120245
120370
  children: [
120246
120371
  /* @__PURE__ */ jsxs("span", {
120247
120372
  className: "text-ink",
120248
120373
  children: [label, required ? " *" : ""]
120249
120374
  }),
120250
120375
  control(),
120376
+ suggestion !== void 0 && isBlank(value) ? /* @__PURE__ */ jsxs("span", {
120377
+ "data-webskill-suggestion": key,
120378
+ className: "flex items-center gap-2 text-xs text-muted",
120379
+ children: [
120380
+ /* @__PURE__ */ jsxs("span", { children: ["Suggested: ", String(suggestion.value)] }),
120381
+ suggestion.reason ? /* @__PURE__ */ jsxs("span", { children: [
120382
+ "(",
120383
+ suggestion.reason,
120384
+ ")"
120385
+ ] }) : null,
120386
+ /* @__PURE__ */ jsx("button", {
120387
+ type: "button",
120388
+ "data-webskill-suggestion-use": key,
120389
+ onClick: () => form.setValue(key, suggestion.value),
120390
+ className: "rounded-md border border-border px-2 py-0.5 text-ink transition-colors hover:bg-accent",
120391
+ children: "Use"
120392
+ })
120393
+ ]
120394
+ }) : null,
120251
120395
  props["description"] ? /* @__PURE__ */ jsx("span", {
120252
120396
  className: "text-xs text-muted",
120253
120397
  children: str(props, "description")
@@ -120262,26 +120406,28 @@ function SurfaceField({ form, props }) {
120262
120406
  });
120263
120407
  }
120264
120408
  /** catalog `Form` 的提交 / 取消按钮:提交带表单值,取消不带 */
120265
- function SurfaceFormButtons({ form, props }) {
120409
+ function SurfaceFormButtons({ form, props, scope }) {
120410
+ const submitId = scope ? scope.submitActionId : form.resolveActionId("submit");
120411
+ const cancelId = scope ? scope.cancelActionId : form.resolveActionId("cancel");
120266
120412
  return /* @__PURE__ */ jsxs("div", {
120267
- className: "flex gap-2",
120268
- children: [/* @__PURE__ */ jsx(Button, {
120269
- type: "submit",
120270
- size: "sm",
120271
- "data-webskill-surface-action": form.resolveActionId("submit"),
120272
- children: str(props, "submitLabel", "Submit")
120273
- }), props["cancelLabel"] ? /* @__PURE__ */ jsx(Button, {
120413
+ className: "flex flex-wrap items-center justify-end gap-2",
120414
+ children: [props["cancelLabel"] ? /* @__PURE__ */ jsx(Button, {
120274
120415
  type: "button",
120275
120416
  size: "sm",
120276
120417
  variant: "secondary",
120277
- "data-webskill-surface-action": form.resolveActionId("cancel"),
120278
- onClick: () => form.emit(form.resolveActionId("cancel")),
120418
+ "data-webskill-surface-action": cancelId,
120419
+ onClick: () => form.emit(cancelId, scope),
120279
120420
  children: str(props, "cancelLabel")
120280
- }) : null]
120421
+ }) : null, /* @__PURE__ */ jsx(Button, {
120422
+ type: "submit",
120423
+ size: "sm",
120424
+ "data-webskill-surface-action": submitId,
120425
+ children: str(props, "submitLabel", "Submit")
120426
+ })]
120281
120427
  });
120282
120428
  }
120283
120429
  /** catalog `Button` 的唯一实现:submit 走带值提交,其余走裸动作 */
120284
- function SurfaceButton({ form, props, nodeId }) {
120430
+ function SurfaceButton({ form, props, nodeId, scope }) {
120285
120431
  const intent = str(props, "action");
120286
120432
  const actionId = form.resolveActionId(intent, nodeId);
120287
120433
  return /* @__PURE__ */ jsx(Button, {
@@ -120289,11 +120435,92 @@ function SurfaceButton({ form, props, nodeId }) {
120289
120435
  type: "button",
120290
120436
  disabled: props["disabled"] === true,
120291
120437
  "data-webskill-surface-action": actionId,
120292
- onClick: () => intent === "submit" ? form.submit(intent, nodeId) : form.emit(actionId),
120438
+ onClick: () => intent === "submit" ? form.submit(intent, nodeId, scope) : form.emit(actionId, scope),
120293
120439
  children: str(props, "label")
120294
120440
  });
120295
120441
  }
120296
120442
  /**
120443
+ * FR-6.2 的四个布局/展示组件。四档渲染共用同一份实现:
120444
+ * native 的 switch 与 json-render / OpenUI 的组件表都调这里,
120445
+ * 语义(tablist、grid、ol/li、progressbar)因此不会随渲染器分叉。
120446
+ */
120447
+ const num = (props, key, fallback) => typeof props[key] === "number" ? props[key] : fallback;
120448
+ const list = (value) => Array.isArray(value) ? value : [];
120449
+ function SpecTabs({ props, children }) {
120450
+ const labels = list(props["labels"]);
120451
+ const panels = Array.isArray(children) ? children : [children];
120452
+ const [active, setActive] = useState(0);
120453
+ const index = Math.min(active, Math.max(panels.length - 1, 0));
120454
+ return /* @__PURE__ */ jsxs("div", {
120455
+ className: "flex flex-col gap-3",
120456
+ children: [/* @__PURE__ */ jsx("div", {
120457
+ role: "tablist",
120458
+ className: "flex gap-1 border-b border-border",
120459
+ children: labels.map((label, position) => /* @__PURE__ */ jsx(Button, {
120460
+ role: "tab",
120461
+ type: "button",
120462
+ size: "sm",
120463
+ variant: position === index ? "secondary" : "ghost",
120464
+ "aria-selected": position === index,
120465
+ onClick: () => setActive(position),
120466
+ children: label
120467
+ }, position))
120468
+ }), panels[index] ?? null]
120469
+ });
120470
+ }
120471
+ function SpecGrid({ props, children }) {
120472
+ return /* @__PURE__ */ jsx("div", {
120473
+ className: "grid gap-3",
120474
+ style: { gridTemplateColumns: `repeat(${Math.min(4, Math.max(2, num(props, "columns", 2)))}, minmax(0, 1fr))` },
120475
+ children
120476
+ });
120477
+ }
120478
+ function SpecTimeline({ props }) {
120479
+ return /* @__PURE__ */ jsx("ol", {
120480
+ className: "flex flex-col gap-2 pl-4",
120481
+ children: list(props["items"]).map((item, index) => /* @__PURE__ */ jsxs("li", {
120482
+ className: "flex flex-col gap-0.5",
120483
+ "data-state": str(item, "state", "pending"),
120484
+ children: [
120485
+ /* @__PURE__ */ jsx("strong", {
120486
+ className: "text-sm text-ink",
120487
+ children: str(item, "title")
120488
+ }),
120489
+ item["time"] ? /* @__PURE__ */ jsx("p", {
120490
+ className: "text-xs text-muted",
120491
+ children: str(item, "time")
120492
+ }) : null,
120493
+ item["description"] ? /* @__PURE__ */ jsx("p", {
120494
+ className: "text-sm text-ink",
120495
+ children: str(item, "description")
120496
+ }) : null
120497
+ ]
120498
+ }, index))
120499
+ });
120500
+ }
120501
+ function SpecProgress({ props }) {
120502
+ const value = Math.max(0, Math.min(100, num(props, "value", 0)));
120503
+ const label = str(props, "label");
120504
+ return /* @__PURE__ */ jsxs("div", {
120505
+ className: "flex flex-col gap-1",
120506
+ children: [label ? /* @__PURE__ */ jsx("span", {
120507
+ className: "text-xs text-muted",
120508
+ children: label
120509
+ }) : null, /* @__PURE__ */ jsx("div", {
120510
+ role: "progressbar",
120511
+ "aria-label": label || "Progress",
120512
+ "aria-valuenow": value,
120513
+ "aria-valuemin": 0,
120514
+ "aria-valuemax": 100,
120515
+ className: "h-2 overflow-hidden rounded-full bg-secondary",
120516
+ children: /* @__PURE__ */ jsx("span", {
120517
+ className: "block h-full bg-ink",
120518
+ style: { width: `${value}%` }
120519
+ })
120520
+ })]
120521
+ });
120522
+ }
120523
+ /**
120297
120524
  * json-render 与 OpenUI 两档的 Renderer 都只把 props 交给组件实现,拿不到节点 id,
120298
120525
  * 也拿不到表单状态,因此表单值与动作回传统一走这个 Context。
120299
120526
  * 缺省值故意不给空实现:没包 Provider 就是宿主接线错了,必须失败而不是“点了没反应”。
@@ -120317,6 +120544,8 @@ function CatalogSurfaceProvider({ surfaceId, spec, actions, onAction, children }
120317
120544
  children
120318
120545
  });
120319
120546
  }
120547
+ /** 当前子树所属的表单作用域;surface 上只有一个表单时为 undefined(行为与放宽前一致) */
120548
+ const FormScopeContext = createContext(void 0);
120320
120549
  /** 把实现表的条目包成真正的 React 组件,使其内部的 hook 调用处于自己的渲染周期 */
120321
120550
  function CatalogNode({ name, props, children }) {
120322
120551
  const Impl = catalogComponentImpls[name];
@@ -120328,40 +120557,47 @@ function CatalogNode({ name, props, children }) {
120328
120557
  }
120329
120558
  function CatalogForm({ props, children }) {
120330
120559
  const form = useCatalogSurfaceForm();
120331
- return /* @__PURE__ */ jsxs("form", {
120332
- className: "flex flex-col gap-3",
120333
- noValidate: true,
120334
- onSubmit: (event) => {
120335
- event.preventDefault();
120336
- form.submit("submit");
120337
- },
120338
- children: [
120339
- props["title"] ? /* @__PURE__ */ jsx("h3", {
120340
- className: "text-sm font-semibold text-ink",
120341
- children: str(props, "title")
120342
- }) : null,
120343
- children,
120344
- /* @__PURE__ */ jsx(SurfaceFormButtons, {
120345
- form,
120346
- props
120347
- })
120348
- ]
120560
+ const scope = form.claimScope(useId(), props);
120561
+ return /* @__PURE__ */ jsx(FormScopeContext.Provider, {
120562
+ value: scope,
120563
+ children: /* @__PURE__ */ jsxs("form", {
120564
+ className: "flex flex-col gap-3",
120565
+ noValidate: true,
120566
+ onSubmit: (event) => {
120567
+ event.preventDefault();
120568
+ form.submit("submit", void 0, scope);
120569
+ },
120570
+ children: [
120571
+ props["title"] ? /* @__PURE__ */ jsx("h3", {
120572
+ className: "text-sm font-semibold text-ink",
120573
+ children: str(props, "title")
120574
+ }) : null,
120575
+ children,
120576
+ /* @__PURE__ */ jsx(SurfaceFormButtons, {
120577
+ form,
120578
+ props,
120579
+ scope
120580
+ })
120581
+ ]
120582
+ })
120349
120583
  });
120350
120584
  }
120351
120585
  function CatalogField({ props }) {
120352
120586
  return /* @__PURE__ */ jsx(SurfaceField, {
120353
120587
  form: useCatalogSurfaceForm(),
120354
- props
120588
+ props,
120589
+ scope: useContext(FormScopeContext)
120355
120590
  });
120356
120591
  }
120357
120592
  function CatalogButton({ props }) {
120358
120593
  return /* @__PURE__ */ jsx(SurfaceButton, {
120359
120594
  form: useCatalogSurfaceForm(),
120360
- props
120595
+ props,
120596
+ scope: useContext(FormScopeContext)
120361
120597
  });
120362
120598
  }
120363
120599
  /**
120364
- * catalog 16 个组件的展示实现:json-render 与 OpenUI 两档共用同一份,
120600
+ * catalog 展示类组件的实现:json-render 与 OpenUI 两档共用同一份,
120365
120601
  * 避免"一个 catalog、多套 registry"退化成多套各自演进的视觉。
120366
120602
  * 交互(表单值收集 / action 回传)由各档的宿主组件负责。
120367
120603
  */
@@ -120433,6 +120669,16 @@ const catalogComponentImpls = {
120433
120669
  });
120434
120670
  },
120435
120671
  Chart: ({ props }) => /* @__PURE__ */ jsx(EChart, { chart: chartSpecFromProps(props) }),
120672
+ Tabs: ({ props, children }) => /* @__PURE__ */ jsx(SpecTabs, {
120673
+ props,
120674
+ children
120675
+ }),
120676
+ Grid: ({ props, children }) => /* @__PURE__ */ jsx(SpecGrid, {
120677
+ props,
120678
+ children
120679
+ }),
120680
+ Timeline: ({ props }) => /* @__PURE__ */ jsx(SpecTimeline, { props }),
120681
+ Progress: ({ props }) => /* @__PURE__ */ jsx(SpecProgress, { props }),
120436
120682
  FileLink: ({ props }) => /* @__PURE__ */ jsx("span", {
120437
120683
  className: "text-sm text-ink",
120438
120684
  children: str(props, "label", str(props, "path"))
@@ -120456,4 +120702,4 @@ const catalogComponentImpls = {
120456
120702
  };
120457
120703
 
120458
120704
  //#endregion
120459
- export { DropdownMenuContent as _, SurfaceField as a, Markdown as b, str as c, Badge as d, Button as f, DropdownMenuCheckboxItem as g, DropdownMenu as h, SurfaceButton as i, useCatalogSurfaceForm as l, DataTable as m, CatalogSurfaceProvider as n, SurfaceFormButtons as o, Checkbox as p, EChart as r, catalogComponentImpls as s, CatalogNode as t, useSurfaceForm as u, DropdownMenuTrigger as v, Separator as x, Input as y };
120705
+ export { Input as C, DropdownMenuTrigger as S, Separator as T, Checkbox as _, SpecProgress as a, DropdownMenuCheckboxItem as b, SurfaceButton as c, catalogComponentImpls as d, str as f, Button as g, Badge as h, SpecGrid as i, SurfaceField as l, useSurfaceForm as m, CatalogSurfaceProvider as n, SpecTabs as o, useCatalogSurfaceForm as p, EChart as r, SpecTimeline as s, CatalogNode as t, SurfaceFormButtons as u, DataTable as v, Markdown as w, DropdownMenuContent as x, DropdownMenu as y };