@dsh-plus/web-search-services 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -4,50 +4,18 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
- let react = require("react");
8
7
  let react_jsx_runtime = require("react/jsx-runtime");
9
- let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
8
+ let react = require("react");
9
+ require("@deepseek-ai/dsh-client-ui-primitives");
10
10
  //#region ../shared/src/client/card.tsx
11
11
  const IDLE_STATUS = {
12
12
  kind: "idle",
13
13
  text: ""
14
14
  };
15
- /** 状态行 + 动作按钮(两种形态共用,类名随形态切换度量)。 */
16
- function CardFoot(props) {
17
- const p = props.prefix;
18
- const section = props.variant === "section";
19
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
20
- className: section ? `${p}-sectionFooter` : `${p}-footer`,
21
- children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
22
- className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
23
- role: "status",
24
- children: props.status.text
25
- }) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
26
- type: "button",
27
- className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
28
- disabled: action.disabled === true,
29
- onClick: action.onClick,
30
- children: action.label
31
- }, action.key))]
32
- });
33
- }
34
- /** 只读提示 + 字段区 + 页脚(两种形态共用)。 */
35
- function CardBody(props) {
36
- const p = props.prefix;
37
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
38
- props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
39
- className: `${p}-readOnly`,
40
- role: "status",
41
- children: props.readOnlyNotice
42
- }) : null,
43
- props.children,
44
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardFoot, { ...props })
45
- ] });
46
- }
47
15
  function CardChrome(props) {
48
16
  const p = props.prefix;
49
17
  const badge = props.statusBadge;
50
- if (props.variant === "section") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
18
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
51
19
  className: `${p}-section`,
52
20
  "aria-label": props.title,
53
21
  children: [
@@ -72,50 +40,37 @@ window.__ModuleLoader__.load({
72
40
  className: `${p}-sectionDesc`,
73
41
  children: props.description
74
42
  }),
75
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
43
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
76
44
  className: `${p}-sectionBody`,
77
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardBody, { ...props })
45
+ children: [
46
+ props.readOnlyNotice !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
47
+ className: `${p}-readOnly`,
48
+ role: "status",
49
+ children: props.readOnlyNotice
50
+ }) : null,
51
+ props.children,
52
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
53
+ className: `${p}-sectionFooter`,
54
+ children: [props.status !== void 0 && props.status.kind !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
55
+ className: `${p}-status${props.status.kind === "error" ? ` ${p}-statusError` : ""}`,
56
+ role: "status",
57
+ children: props.status.text
58
+ }) : null, props.actions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
59
+ type: "button",
60
+ className: `${p}-btn ${action.variant === "primary" ? `${p}-btnPrimary` : `${p}-btnGhost`}`,
61
+ disabled: action.disabled === true,
62
+ onClick: action.onClick,
63
+ children: action.label
64
+ }, action.key))]
65
+ })
66
+ ]
78
67
  })
79
68
  ]
80
69
  });
81
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
82
- className: `${p}-card${props.open ? ` ${p}-cardOpen` : ""}`,
83
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
84
- type: "button",
85
- className: `${p}-header`,
86
- "aria-expanded": props.open,
87
- "aria-label": props.title,
88
- onClick: () => props.onToggle(!props.open),
89
- children: [
90
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
91
- className: `${p}-headText`,
92
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
93
- className: `${p}-name`,
94
- children: props.title
95
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
96
- className: `${p}-description`,
97
- children: props.description
98
- })]
99
- }),
100
- badge !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
101
- className: `${p}-statusBadge ${badge.on ? `${p}-statusOn` : `${p}-statusOff`}`,
102
- children: badge.text
103
- }) : null,
104
- props.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
105
- className: `${p}-pending`,
106
- children: props.dirtyLabel
107
- }) : null,
108
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: `${p}-chevron${props.open ? ` ${p}-chevronOpen` : ""}` })
109
- ]
110
- }), props.open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
111
- className: `${p}-body`,
112
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardBody, { ...props })
113
- }) : null]
114
- });
115
70
  }
116
71
  /** 取值未到达时的占位:与 CardChrome 同形态,避免宿主页里闪一次卡片外壳。 */
117
72
  function CardLoading(props) {
118
- if (props.variant === "section") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
73
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
119
74
  className: `${props.prefix}-section`,
120
75
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
121
76
  className: `${props.prefix}-readOnly`,
@@ -123,41 +78,20 @@ window.__ModuleLoader__.load({
123
78
  children: props.text
124
79
  })
125
80
  });
126
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
127
- className: `${props.prefix}-card`,
128
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
129
- className: `${props.prefix}-readOnly`,
130
- role: "status",
131
- children: props.text
132
- })
133
- });
134
81
  }
135
82
  //#endregion
136
83
  //#region ../shared/src/client/config-slots.ts
137
84
  /** dsh-plus 聚合 bundle 的包名(各插件 row 均经其补丁层插入 profile)。 */
138
85
  const DSH_PLUS_BUNDLE = "@dsh-plus/bundle-main";
139
86
  /**
140
- * 视图 → 外壳形态:插件页 page 视图渲染在官方页面容器内(宿主已画标题、图标、
141
- * 面包屑与页面级内边距),再套卡片会形成卡片套卡片并压缩移动端可用宽度,
142
- * 故用无边框分节;summary 与 legacy 槽位保持卡片形态。
143
- */
144
- function cardVariantFor(view) {
145
- return view === "page" ? "section" : "card";
146
- }
147
- /**
148
- * 把一张配置卡片同时注册进 legacy 与新版三个槽位。
149
- * 任一槽位在当前 dsh 版本未声明时对应 inject 挂起等待,版本不命中即 no-op。
87
+ * 把一张配置卡片注册进插件页的两个配置槽位。
88
+ * 两个槽位都由 0.2.1-alpha.1 的插件页声明,任一缺席即报错——不做版本探测。
150
89
  */
151
90
  function injectPluginConfigCard(slots, reg) {
152
91
  const base = {
153
92
  locale: reg.ns,
154
93
  inject: reg.inject
155
94
  };
156
- slots.inject("settings.plugin.item", () => slots.register({
157
- name: "settings.plugin.item",
158
- key: reg.ns,
159
- ...base
160
- }, reg.component));
161
95
  slots.inject("plugins.row.config", () => slots.register({
162
96
  name: "plugins.row.config",
163
97
  key: `${DSH_PLUS_BUNDLE}#${reg.rowId}`,
@@ -421,36 +355,33 @@ window.__ModuleLoader__.load({
421
355
  //#endregion
422
356
  //#region ../shared/src/client/styles.ts
423
357
  /**
424
- * 配置卡片样式工厂(各插件 client 的公共收编版)。
425
- * 视觉规则与迁移前逐字一致(类名前缀换为各插件自身,DOM 类名不变),
426
- * 另补移动端与可达性增强(767px 断点 + pointer:coarse,对齐 ui-mobile-fit 约定):
358
+ * 配置分节样式工厂(各插件 client 的公共收编版)。
359
+ *
360
+ * 目标宿主 dsh 0.2.1-alpha.1:插件页把配置视图放进已有页面级内边距的容器里
361
+ * (`div.detailSections[data-plugin-config]` 或 `section.detailSection[data-plugin-config]`),
362
+ * 外层无边框——故这里输出的是**无边框分节**(小节标题 13px/600、字段 12px 0、
363
+ * 横向零内边距、页脚非 sticky),度量对齐官方设置页
364
+ * (`@deepseek-ai/dsh-client-ui-primitives` 的 settings-form)。
365
+ *
366
+ * 移动端与可达性(767px 断点 + pointer:coarse,对齐 ui-mobile-fit 约定):
427
367
  * - 窄屏 input/textarea 16px(防 iOS 聚焦缩放)、可点目标 ≥44px;
428
- * - footer 按钮等宽换行、状态文字独占一行;
429
- * - 展开态 body 底部 sticky 保存栏(长表单滚动中始终可达)。
430
- * - 分节形态(-section,插件页 page 视图内嵌宿主页面):无边框/背景、横向零
431
- * 内边距,页脚不 sticky——官方插件页已提供页面级内边距,再叠一层卡片会
432
- * 缩窄移动端可用宽度(卡片套卡片)。
368
+ * - 页脚按钮等宽换行、状态文字独占一行。
433
369
  * 沿用官方 data-plugin / data-plugin-css 约定(HMR 据此卸载),不覆盖上游选择器。
434
370
  * @module @dsh-plus/shared/client/styles
435
371
  */
436
- /** 生成全套卡片 CSS;prefix 为插件类名前缀(如 'dne'),extra 为插件特有规则。 */
372
+ /** 生成全套分节 CSS;prefix 为插件类名前缀(如 'dne'),extra 为插件特有规则。 */
437
373
  function cardCss(prefix, extra = "") {
438
374
  return `
439
- .${prefix}-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}
440
- .${prefix}-card:hover{border-color:var(--dsw-alias-label-dimmed)}
441
- .${prefix}-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}
442
- .${prefix}-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}
443
- .${prefix}-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}
444
- .${prefix}-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}
445
- .${prefix}-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}
446
- .${prefix}-description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
447
- .${prefix}-chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;display:inline-flex}
448
- .${prefix}-chevronOpen{transform:rotate(180deg)}
375
+ .${prefix}-section{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;padding:16px 0;display:flex}
376
+ .${prefix}-sectionHead{align-items:center;gap:8px;min-width:0;display:flex}
377
+ .${prefix}-sectionTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}
378
+ .${prefix}-sectionBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
379
+ .${prefix}-sectionDesc{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}
380
+ .${prefix}-sectionBody{flex-direction:column;min-width:0;display:flex}
381
+ .${prefix}-sectionFooter{align-items:center;gap:8px;padding-top:16px;display:flex;flex-wrap:wrap}
449
382
  .${prefix}-pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
450
- .${prefix}-statusBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
451
383
  .${prefix}-statusOn{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary)}
452
384
  .${prefix}-statusOff{color:var(--dsw-alias-label-tertiary)}
453
- .${prefix}-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
454
385
  .${prefix}-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}
455
386
  .${prefix}-field+.${prefix}-field{border-top:1px solid var(--dsw-alias-border-l2)}
456
387
  .${prefix}-head{align-items:center;gap:8px;display:flex}
@@ -476,19 +407,9 @@ window.__ModuleLoader__.load({
476
407
  .${prefix}-checkRow input:checked::after{left:16px;background:var(--dsw-alias-bg-base)}
477
408
  .${prefix}-checkRow input:disabled{opacity:.4;cursor:default}
478
409
  .${prefix}-checkRow input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
479
- /* 宿主内嵌分节形态(插件页 page 视图):官方设置页同构——无边框/背景,
480
- 横向零内边距(宽度交给宿主页面容器),小节标题 13px/600,页脚非 sticky。 */
481
- .${prefix}-section{box-sizing:border-box;flex-direction:column;width:100%;min-width:0;padding:16px 0;display:flex}
482
- .${prefix}-sectionHead{align-items:center;gap:8px;min-width:0;display:flex}
483
- .${prefix}-sectionTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}
484
- .${prefix}-sectionBadge{white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
485
- .${prefix}-sectionDesc{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}
486
- .${prefix}-sectionBody{flex-direction:column;min-width:0;display:flex}
487
- .${prefix}-sectionFooter{align-items:center;gap:8px;padding-top:16px;display:flex;flex-wrap:wrap}
488
410
  .${prefix}-groupLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;padding:12px 0 2px;margin:0}
489
411
  .${prefix}-readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}
490
412
  .${prefix}-warn{color:var(--dsw-alias-label-error);margin:12px 0 0;font-size:12px;line-height:1.5}
491
- .${prefix}-footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex;flex-wrap:wrap}
492
413
  .${prefix}-status{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;margin:0;font-size:12px;line-height:1.5}
493
414
  .${prefix}-statusError{color:var(--dsw-alias-label-error)}
494
415
  .${prefix}-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}
@@ -498,16 +419,10 @@ window.__ModuleLoader__.load({
498
419
  .${prefix}-btn:disabled{opacity:.4;cursor:default}
499
420
  .${prefix}-btn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}
500
421
  @media (max-width:767px){
501
- .${prefix}-body{margin:0 10px}
502
- .${prefix}-header{padding:12px 12px}
503
422
  .${prefix}-input,.${prefix}-select{font-size:16px;height:40px}
504
423
  .${prefix}-checkRow{min-height:44px;padding:8px 0}
505
- .${prefix}-footer{position:sticky;bottom:0;background:var(--dsw-alias-bg-layer-2);margin:0 -10px;padding:10px 10px 6px;border-top:1px solid var(--dsw-alias-border-l2);border-bottom-left-radius:12px;border-bottom-right-radius:12px}
506
424
  .${prefix}-status{flex-basis:100%;flex:none}
507
425
  .${prefix}-btn{min-height:44px;flex:1;min-width:96px}
508
- .${prefix}-statusBadge{display:none}
509
- .${prefix}-sectionBadge{display:inline-block}
510
- .${prefix}-sectionFooter{position:static}
511
426
  }
512
427
  @media (pointer:coarse){
513
428
  .${prefix}-btn{min-height:44px}
@@ -608,9 +523,8 @@ ${extra}
608
523
  //#endregion
609
524
  //#region src/client/card.tsx
610
525
  /**
611
- * 「搜索后端聚合」配置卡片:经 injectPluginConfigCard 注册(legacy
612
- * settings.plugin.item 与插件页 plugins.row.config / plugins.bundle.config,
613
- * view 分发 summary/page)。
526
+ * 「搜索后端聚合」配置卡片:经 injectPluginConfigCard 注册(插件页
527
+ * plugins.row.config / plugins.bundle.config,view 分发 summary/page)。
614
528
  * 字段:scriptPath / envFile / python / priority(每行一个后端)/ timeoutMs。
615
529
  * 密钥不走卡片:keys 段的 role(secret) 字段只允许 profile 行级注入,用户层
616
530
  * 写入会被脱敏遮蔽——卡片改为把密钥来源(env 文件)与覆盖方式写在页面上。
@@ -627,12 +541,9 @@ ${extra}
627
541
  patch: toPatch,
628
542
  saveFailedLabel: t("saveFailed")
629
543
  });
630
- const [open, setOpen] = (0, react.useState)(props.view === "page");
631
544
  if (props.view === "summary") return t("summaryLine");
632
- const variant = cardVariantFor(props.view);
633
545
  if (draft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CardLoading, {
634
546
  prefix: "wsv",
635
- variant,
636
547
  text: t("loading")
637
548
  });
638
549
  const priorityInvalid = !priorityTextOk(draft.priorityText);
@@ -641,9 +552,6 @@ ${extra}
641
552
  prefix: "wsv",
642
553
  title: t("title"),
643
554
  description: t("description"),
644
- open,
645
- onToggle: setOpen,
646
- variant,
647
555
  dirty,
648
556
  dirtyLabel: t("unsaved"),
649
557
  readOnlyNotice: disabled ? t("readOnly") : void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-plus/web-search-services",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "dsh-plus service plugin: web_search 免费后端聚合——经官方 ctx.web provider 扩展点桥接 search-services skill(Tavily/Exa/OpenAI Chat 免费额度,优先级+自动回退+key 配置),官方 web_search 工具与输出格式零修改",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -32,21 +32,21 @@
32
32
  }
33
33
  },
34
34
  "dependencies": {
35
- "@dsh-plus/shared": "0.1.31"
35
+ "@dsh-plus/shared": "0.1.33"
36
36
  },
37
37
  "peerDependencies": {
38
- "@deepseek-ai/cordis": "^4.0.4",
39
- "@deepseek-ai/dsh-home-paths": "^0.2.0-rc.1",
40
- "@deepseek-ai/dsh-settings": "^0.2.0-rc.1",
41
- "@deepseek-ai/dsh-web": "^0.2.0-rc.1",
42
- "@deepseek-ai/schemastery": "^3.18.4"
38
+ "@deepseek-ai/cordis": "^4.0.5-alpha.1",
39
+ "@deepseek-ai/dsh-home-paths": "^0.2.1-alpha.1",
40
+ "@deepseek-ai/dsh-settings": "^0.2.1-alpha.1",
41
+ "@deepseek-ai/dsh-web": "^0.2.1-alpha.1",
42
+ "@deepseek-ai/schemastery": "^3.18.5-alpha.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@deepseek-ai/cordis": "4.0.4",
46
- "@deepseek-ai/dsh-home-paths": "0.2.0-rc.1",
47
- "@deepseek-ai/dsh-settings": "0.2.0-rc.1",
48
- "@deepseek-ai/dsh-web": "0.2.0-rc.1",
49
- "@deepseek-ai/schemastery": "3.18.4",
45
+ "@deepseek-ai/cordis": "4.0.5-alpha.1",
46
+ "@deepseek-ai/dsh-home-paths": "0.2.1-alpha.1",
47
+ "@deepseek-ai/dsh-settings": "0.2.1-alpha.1",
48
+ "@deepseek-ai/dsh-web": "0.2.1-alpha.1",
49
+ "@deepseek-ai/schemastery": "3.18.5-alpha.1",
50
50
  "@types/react": "~18.3.31",
51
51
  "react": "^18.2.0"
52
52
  },
@@ -1,7 +1,6 @@
1
1
  /**
2
- * 「搜索后端聚合」配置卡片:经 injectPluginConfigCard 注册(legacy
3
- * settings.plugin.item 与插件页 plugins.row.config / plugins.bundle.config,
4
- * view 分发 summary/page)。
2
+ * 「搜索后端聚合」配置卡片:经 injectPluginConfigCard 注册(插件页
3
+ * plugins.row.config / plugins.bundle.config,view 分发 summary/page)。
5
4
  * 字段:scriptPath / envFile / python / priority(每行一个后端)/ timeoutMs。
6
5
  * 密钥不走卡片:keys 段的 role(secret) 字段只允许 profile 行级注入,用户层
7
6
  * 写入会被脱敏遮蔽——卡片改为把密钥来源(env 文件)与覆盖方式写在页面上。
@@ -13,14 +12,13 @@
13
12
  import {
14
13
  CardChrome,
15
14
  CardLoading,
16
- cardVariantFor,
17
15
  type NamespaceSettingsApi,
18
16
  type PluginConfigViewProps,
19
17
  type Scope,
20
18
  TextField,
21
19
  useNamespaceDraft,
22
20
  } from '@dsh-plus/shared/client'
23
- import { type ReactElement, useState } from 'react'
21
+ import type { ReactElement } from 'react'
24
22
 
25
23
  import {
26
24
  type ConfigValue,
@@ -45,14 +43,11 @@ export function WebSearchServicesCard(props: CardProps): ReactElement | string |
45
43
  Draft
46
44
  >({ scope, api, from: draftFromValue, patch: toPatch, saveFailedLabel: t('saveFailed') })
47
45
  // 插件页 page 视图为表单落地页,默认展开;旧槽位无 view,保持折叠。
48
- const [open, setOpen] = useState(props.view === 'page')
49
46
 
50
47
  // 插件页 summary 视图只出一行简介(hooks 已全部落定,可安全提前返回)。
51
48
  if (props.view === 'summary') return t('summaryLine')
52
49
 
53
- // 插件页 page 视图内嵌宿主页面容器(已带页面级内边距与标题),用无边框分节。
54
- const variant = cardVariantFor(props.view)
55
- if (draft === null) return <CardLoading prefix="wsv" variant={variant} text={t('loading')} />
50
+ if (draft === null) return <CardLoading prefix="wsv" text={t('loading')} />
56
51
 
57
52
  const priorityInvalid = !priorityTextOk(draft.priorityText)
58
53
  const timeoutInvalid = !timeoutTextOk(draft.timeoutMsText)
@@ -61,9 +56,6 @@ export function WebSearchServicesCard(props: CardProps): ReactElement | string |
61
56
  prefix="wsv"
62
57
  title={t('title')}
63
58
  description={t('description')}
64
- open={open}
65
- onToggle={setOpen}
66
- variant={variant}
67
59
  dirty={dirty}
68
60
  dirtyLabel={t('unsaved')}
69
61
  readOnlyNotice={disabled ? t('readOnly') : undefined}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 浏览器半入口:注册 locale 字典 + 注册「搜索后端聚合」卡片
3
- * (injectPluginConfigCard 三槽位:legacy settings.plugin.item 与插件页
4
- * plugins.row.config / plugins.bundle.config)。
3
+ * (injectPluginConfigCard 两槽位:插件页 plugins.row.config /
4
+ * plugins.bundle.config)。
5
5
  * 构建产物为 window.__ModuleLoader__.load({id, factory}) 形式的 CJS factory
6
6
  * (包装见 tsdown.config.ts);样式沿用官方 data-plugin-css 约定,HMR 据此卸载。
7
7
  * 配置读写经 ctx.remote.settings 直连(scope/api 来自 @dsh-plus/shared/client);