@klarkxy/dsh-web-search-manager 0.3.0 → 0.3.2
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/README.md +14 -14
- package/docs/README.zh-CN.md +13 -13
- package/lib/client.inner.cjs +124 -72
- package/lib/client.inner.cjs.map +1 -1
- package/lib/client.js +124 -72
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[简体中文](docs/README.zh-CN.md)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Pick which service answers the model's web searches, set request limits, and let it read public pages — from one settings page with separate tabs for search, page reading, and request limits.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -12,39 +12,39 @@ Choose which service answers the model's web searches, set request limits, and l
|
|
|
12
12
|
dsh plugin --profile web add @klarkxy/dsh-web-search-manager
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Replace `web` with your profile name
|
|
15
|
+
Replace `web` with your profile name. Restart DSH Web, then open **Settings → Web Search**. Restart the profile after plugin updates as well so the new search code loads.
|
|
16
16
|
|
|
17
17
|
## Set up search
|
|
18
18
|
|
|
19
|
-
DuckDuckGo works out of the box with
|
|
19
|
+
DuckDuckGo works out of the box with zero configuration. To use DeepSeek Search, Exa, Brave, Bocha, Serper, Firecrawl, Tavily, Perplexity, or You.com, enter its API key. Drag the list to reorder: each search uses the first ready service. Search services from other plugins, such as Zhihu, appear in the same list and join the priority order once you enable them.
|
|
20
20
|
|
|
21
|
-
The **Settings** tab sets the number of results, queries per call,
|
|
21
|
+
The **Settings** tab sets the number of results, queries per call, total timeout, and maximum page length.
|
|
22
22
|
|
|
23
23
|
## Read web pages
|
|
24
24
|
|
|
25
|
-
Turn on **Read web pages**, enable the services you want
|
|
25
|
+
Turn on **Read web pages**, enable the services you want, then drag them or use the up/down arrow keys to set priority. Each fetch uses the first configured, available service. Fetch services from other plugins also appear and join the priority order once enabled; temporarily unloaded services keep their selection and position.
|
|
26
26
|
|
|
27
|
-
Your previously selected fetch service
|
|
27
|
+
Your previously selected fetch service stays first. The bundled **Read web pages** service uses the free Jina Reader and falls back to one direct request if that fails; services from the host or other plugins use their own fetching method.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
**Firecrawl** can also read Markdown pages with the same API key as Firecrawl search; search and page reads are billed separately. Perplexity uses its Search API to return search results directly; You.com returns web and news snippets directly.
|
|
30
30
|
|
|
31
31
|
## Give the tools to the model
|
|
32
32
|
|
|
33
|
-
Add this to the plugin list of
|
|
33
|
+
Add this to the plugin list of your `agent.cordis.yml`:
|
|
34
34
|
|
|
35
35
|
```yaml
|
|
36
36
|
- name: '@klarkxy/dsh-web-search-manager/tools'
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
The model then gets `web_search` and `web_fetch` while search and fetch are
|
|
39
|
+
The model then gets `web_search` and `web_fetch` while search and fetch are on.
|
|
40
40
|
|
|
41
41
|
## Limits
|
|
42
42
|
|
|
43
|
-
- Paid services may charge
|
|
44
|
-
-
|
|
45
|
-
- Firecrawl page reads require a page status code and final URL in the
|
|
46
|
-
-
|
|
47
|
-
- Cancellation and timeouts ask the active service to stop and wait for it to finish cleaning up. A third-party service that ignores cancellation can delay
|
|
43
|
+
- Paid services may charge per search or fetch; refer to your provider account for billing.
|
|
44
|
+
- The bundled Jina Reader sends page addresses to Jina; use it only for public URLs free of private tokens.
|
|
45
|
+
- Firecrawl page reads require a page status code and final URL in the response, and may serve cached page content. URLs are sent to the selected fetch service.
|
|
46
|
+
- Each search or fetch request runs against the selected active service only.
|
|
47
|
+
- Cancellation and timeouts ask the active service to stop and wait for it to finish cleaning up. A third-party service that ignores cancellation can delay results and plugin unloading, as code running inside DSH finishes cooperatively.
|
|
48
48
|
|
|
49
49
|
## License
|
|
50
50
|
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[English](../README.md)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
在一个设置页里选择由哪个服务回答模型的网络搜索、设置请求限制,并让模型读取公开网页。搜索服务、网页读取、请求限制各占一个页签。
|
|
8
8
|
|
|
9
9
|
## 安装
|
|
10
10
|
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
dsh plugin --profile web add @klarkxy/dsh-web-search-manager
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
把 `web` 换成你的 profile
|
|
15
|
+
把 `web` 换成你的 profile 名。重启 DSH Web 后打开「设置 → 网页搜索」。更新插件后同样重启 profile,以加载新版搜索代码。
|
|
16
16
|
|
|
17
17
|
## 配置搜索
|
|
18
18
|
|
|
19
|
-
DuckDuckGo
|
|
19
|
+
DuckDuckGo 开箱即用。要用 DeepSeek 搜索、Exa、Brave、博查、Serper、Firecrawl、Tavily、Perplexity 或 You.com,填写对应 API Key。拖拽列表调整顺序:每次搜索使用第一个就绪的服务。其他插件提供的搜索服务(例如知乎)也在同一列表中,手动开启后即可参与排序。
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
「设置」页签设置结果条数、每次调用的查询数、总超时和网页正文长度上限。
|
|
22
22
|
|
|
23
23
|
## 读取网页
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
打开「网页读取」,选择参与的服务,拖拽或用上下方向键调整优先级。每次读取使用第一个已配置且可用的服务。其他插件接入的读取服务也会出现在列表中,手动开启后加入优先列表;暂时未加载的服务保留原有选择和顺序。
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
原先选中的读取服务保留在首位。内置「网页读取」走免费的 Jina Reader,失败时改为直接请求一次;宿主或其他插件的服务按各自方式读取。
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
也可开启 **Firecrawl** 读取 Markdown 网页,与 Firecrawl 搜索共用 API Key;搜索与网页读取分别计费。Perplexity 使用 Search API 直接返回搜索结果;You.com 直接返回网页与新闻摘要。
|
|
30
30
|
|
|
31
31
|
## 让模型使用
|
|
32
32
|
|
|
@@ -36,15 +36,15 @@ DuckDuckGo 默认可用,无需密钥。也可以填写 API Key 启用 DeepSeek
|
|
|
36
36
|
- name: '@klarkxy/dsh-web-search-manager/tools'
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
搜索和网页读取开启时,模型获得 `web_search` 与 `web_fetch` 工具。
|
|
40
40
|
|
|
41
41
|
## 限制
|
|
42
42
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
- Firecrawl
|
|
46
|
-
-
|
|
47
|
-
-
|
|
43
|
+
- 付费服务可能按次收费,实际账单以服务商账户为准。
|
|
44
|
+
- 内置 Jina Reader 会把网址发送给 Jina,请仅用于不含私密令牌的公开链接。
|
|
45
|
+
- Firecrawl 网页读取要求服务返回网页状态码和最终网址,正文可能来自服务缓存。网址会发送给所选服务。
|
|
46
|
+
- 每次搜索或网页读取仅请求当前排在首位的就绪服务。
|
|
47
|
+
- 取消与超时会请求当前服务停止并等待其完成清理。忽略取消的第三方服务可能延迟结果返回和插件卸载,DSH 进程内的代码通过协作方式停止。
|
|
48
48
|
|
|
49
49
|
## 许可证
|
|
50
50
|
|
package/lib/client.inner.cjs
CHANGED
|
@@ -219,6 +219,17 @@ ${scope} {
|
|
|
219
219
|
/* --- Layout scaffolding. --- */
|
|
220
220
|
& .dsh-ui-stack { display: flex; flex-direction: column; gap: 12px; }
|
|
221
221
|
& .dsh-ui-stack-lg { display: flex; flex-direction: column; gap: 20px; }
|
|
222
|
+
/* Plugin detail pages share one reading column. These are layout recipes;
|
|
223
|
+
* controls keep their own primitive styles. Form spacing follows the host's
|
|
224
|
+
* settings-form/fields.module.css and SettingsForm.module.css. */
|
|
225
|
+
& .dsh-ui-page { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 760px; min-width: 0; }
|
|
226
|
+
& .dsh-ui-form { display: flex; flex-direction: column; gap: 0; min-width: 0; }
|
|
227
|
+
&.dsh-ui-form > .dsh-ui-field, & .dsh-ui-form > .dsh-ui-field { padding: 12px 0; }
|
|
228
|
+
& .dsh-ui-form-footer { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding-top: 16px; min-width: 0; }
|
|
229
|
+
& .dsh-ui-fields-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; min-width: 0; margin: 0; padding: 0; border: 0; }
|
|
230
|
+
@media (max-width: 560px) {
|
|
231
|
+
& .dsh-ui-fields-grid { grid-template-columns: minmax(0, 1fr); }
|
|
232
|
+
}
|
|
222
233
|
& .dsh-ui-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
223
234
|
& .dsh-ui-row-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
|
|
224
235
|
& .dsh-ui-spacer { flex: 1; min-width: 0; }
|
|
@@ -246,6 +257,9 @@ ${scope} {
|
|
|
246
257
|
* official primitive, so this only owns the vertical rhythm. --- */
|
|
247
258
|
& .dsh-ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
|
248
259
|
& .dsh-ui-field + .dsh-ui-field { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }
|
|
260
|
+
/* Grid fields share a row, so the stacked-field divider must not win later in
|
|
261
|
+
* the cascade. Reset it here, after the field recipe. */
|
|
262
|
+
& .dsh-ui-fields-grid > .dsh-ui-field { padding: 0; border: 0; }
|
|
249
263
|
& .dsh-ui-label { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--dsw-alias-label-primary); }
|
|
250
264
|
& .dsh-ui-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
|
|
251
265
|
& .dsh-ui-help { font-size: 12px; line-height: 1.6; color: var(--dsw-alias-label-secondary); }
|
|
@@ -436,9 +450,102 @@ ${scope} {
|
|
|
436
450
|
& *, & *::before, & *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
|
|
437
451
|
}
|
|
438
452
|
}
|
|
439
|
-
`.replace(/^& (\.dsh-ui-[a-z0-9-]+)(
|
|
453
|
+
`.replace(/^& (\.dsh-ui-[a-z0-9-]+)(?=\s*\{)/gm, (_match, className) => `&${className}, & ${className}`);
|
|
440
454
|
}
|
|
441
455
|
//#endregion
|
|
456
|
+
//#region src/client-styles.ts
|
|
457
|
+
/**
|
|
458
|
+
* The shared contract paints this page: the type tiers, the card, the field,
|
|
459
|
+
* the button row, the notice, the focus ring and the state colours. What is
|
|
460
|
+
* left here is only the geometry the contract does not cover — the reading
|
|
461
|
+
* width of the panel, the ranked three-column row, the drag affordance, the
|
|
462
|
+
* drop indicator, the screen-reader-only announcer and the limits grid.
|
|
463
|
+
*
|
|
464
|
+
* Nothing below declares a colour of its own beyond naming a host token, and
|
|
465
|
+
* nothing carries a literal fallback: the host publishes both themes and a
|
|
466
|
+
* literal would pin one of them.
|
|
467
|
+
*
|
|
468
|
+
* Every plugin rule nests under the plugin root, as the contract does, so a
|
|
469
|
+
* .ws-* or .web-search-* class never paints a neighbouring plugin. Selectors
|
|
470
|
+
* that start with an element name keep an explicit `&`, the form every
|
|
471
|
+
* nesting implementation accepts.
|
|
472
|
+
*/
|
|
473
|
+
const webSearchClientStyles = `${officialUiCss("ws-root")}
|
|
474
|
+
.ws-root {
|
|
475
|
+
|
|
476
|
+
.ws-card-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding-bottom: 8px; }
|
|
477
|
+
.ws-sr-only {
|
|
478
|
+
position: absolute;
|
|
479
|
+
width: 1px;
|
|
480
|
+
height: 1px;
|
|
481
|
+
padding: 0;
|
|
482
|
+
margin: -1px;
|
|
483
|
+
overflow: hidden;
|
|
484
|
+
clip-path: inset(50%);
|
|
485
|
+
white-space: nowrap;
|
|
486
|
+
border: 0;
|
|
487
|
+
}
|
|
488
|
+
.ws-provider-note { display: flex; align-items: center; gap: 6px; }
|
|
489
|
+
.web-search-provider { display: grid; gap: 8px; min-width: 0; }
|
|
490
|
+
.web-search-provider-info { display: grid; gap: 3px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); overflow-wrap: anywhere; }
|
|
491
|
+
.web-search-provider-heading { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; min-height: 24px; }
|
|
492
|
+
& a { color: var(--dsw-alias-state-business-primary); font-size: 12px; line-height: 18px; text-underline-offset: 3px; }
|
|
493
|
+
/* The primitive renders a 32px control in an inline-flex wrapper; a settings
|
|
494
|
+
* field needs it to fill the column it sits in. */
|
|
495
|
+
.ws-input { width: 100%; }
|
|
496
|
+
.web-search-rank { margin: 0; padding: 0; list-style: none; }
|
|
497
|
+
.web-search-rank li {
|
|
498
|
+
position: relative;
|
|
499
|
+
display: grid;
|
|
500
|
+
grid-template-columns: 24px minmax(0, 1fr) auto;
|
|
501
|
+
gap: 10px;
|
|
502
|
+
align-items: start;
|
|
503
|
+
padding: 14px 0;
|
|
504
|
+
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
505
|
+
}
|
|
506
|
+
& button.web-search-drag-handle {
|
|
507
|
+
display: grid;
|
|
508
|
+
place-items: center;
|
|
509
|
+
width: 24px;
|
|
510
|
+
height: 24px;
|
|
511
|
+
min-height: 24px;
|
|
512
|
+
padding: 0;
|
|
513
|
+
cursor: grab;
|
|
514
|
+
opacity: 0.65;
|
|
515
|
+
}
|
|
516
|
+
& button.web-search-drag-handle:hover { opacity: 1; }
|
|
517
|
+
& button.web-search-drag-handle:active { cursor: grabbing; }
|
|
518
|
+
& button.web-search-drag-handle[aria-disabled='true'] { cursor: wait; opacity: 0.4; }
|
|
519
|
+
.web-search-rank li[data-dragging] { opacity: 0.45; }
|
|
520
|
+
.web-search-rank li[data-drop]::after { content: ''; position: absolute; left: 0; right: 0; height: 2px; background: var(--dsw-alias-state-business-primary); pointer-events: none; }
|
|
521
|
+
.web-search-rank li[data-drop='before']::after { top: -1px; }
|
|
522
|
+
.web-search-rank li[data-drop='after']::after { bottom: -1px; }
|
|
523
|
+
.web-search-rank-index { color: var(--dsw-alias-label-tertiary); font-variant-numeric: tabular-nums; line-height: 24px; }
|
|
524
|
+
.web-search-rank-move { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; padding-top: 2px; }
|
|
525
|
+
.ws-danger:hover:not(:disabled),
|
|
526
|
+
.ws-danger[data-armed] { color: var(--dsw-alias-state-error-primary); border-color: var(--dsw-alias-state-error-primary); }
|
|
527
|
+
.ws-danger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }
|
|
528
|
+
@media (max-width: 560px) {
|
|
529
|
+
.web-search-rank-move { flex-direction: column; align-items: flex-end; }
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
`;
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region ../dsh-plugin-kit/src/contracts.ts
|
|
535
|
+
/** `@klarkxy/dsh-git-commit` becomes `KlarkxyDshGitCommitModelSettingsChanges`. */
|
|
536
|
+
function modelSettingsChangesIdentity(packageName) {
|
|
537
|
+
const scoped = /^@([^/]+)\/(.+)$/.exec(packageName);
|
|
538
|
+
const parts = (scoped ? `${scoped[1]}/${scoped[2]}` : packageName).split(/[^A-Za-z0-9]+/).filter(Boolean);
|
|
539
|
+
if (!parts.length) throw new Error("Model settings package name has no RPC segment");
|
|
540
|
+
const segment = `${parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}ModelSettingsChanges`;
|
|
541
|
+
if (!/^[A-Z][A-Za-z0-9]*$/.test(segment)) throw new Error(`Model settings sync name is not an RPC segment: ${segment}`);
|
|
542
|
+
return {
|
|
543
|
+
service: segment,
|
|
544
|
+
namespace: segment
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
modelSettingsChangesIdentity("@klarkxy/dsh-plugin-kit");
|
|
548
|
+
//#endregion
|
|
442
549
|
//#region ../dsh-plugin-kit/src/client-utils.ts
|
|
443
550
|
/** Fixed pause for failing background reads; manual work is never replayed. */
|
|
444
551
|
function createPluginReadGate(now = Date.now) {
|
|
@@ -1286,7 +1393,7 @@ function NetworkSearchSettings({ client, hidden }) {
|
|
|
1286
1393
|
setNote({ key: "keyDeleted" });
|
|
1287
1394
|
}
|
|
1288
1395
|
if (!status || !limitDraft) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1289
|
-
className: "web-search-settings ws-root dsh-ui-
|
|
1396
|
+
className: "web-search-settings ws-root dsh-ui-page",
|
|
1290
1397
|
children: [loadError ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
1291
1398
|
role: "alert",
|
|
1292
1399
|
className: "dsh-ui-error",
|
|
@@ -1380,7 +1487,7 @@ function NetworkSearchSettings({ client, hidden }) {
|
|
|
1380
1487
|
});
|
|
1381
1488
|
}
|
|
1382
1489
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1383
|
-
className: "web-search-settings ws-root dsh-ui-
|
|
1490
|
+
className: "web-search-settings ws-root dsh-ui-page",
|
|
1384
1491
|
"data-testid": "web-search-settings",
|
|
1385
1492
|
children: [
|
|
1386
1493
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedTabs, {
|
|
@@ -1741,11 +1848,11 @@ function NetworkSearchSettings({ client, hidden }) {
|
|
|
1741
1848
|
hidden: tab !== "limits",
|
|
1742
1849
|
tabIndex: 0,
|
|
1743
1850
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("fieldset", {
|
|
1744
|
-
className: "
|
|
1851
|
+
className: "dsh-ui-fields-grid",
|
|
1745
1852
|
disabled: busy || reordering,
|
|
1746
1853
|
"aria-label": text.tabLimits,
|
|
1747
1854
|
children: LIMITS.map(([key, min, max]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1748
|
-
className: "
|
|
1855
|
+
className: "dsh-ui-field",
|
|
1749
1856
|
children: [
|
|
1750
1857
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1751
1858
|
className: "dsh-ui-label",
|
|
@@ -1784,7 +1891,7 @@ function NetworkSearchSettings({ client, hidden }) {
|
|
|
1784
1891
|
})
|
|
1785
1892
|
}),
|
|
1786
1893
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1787
|
-
className: "dsh-ui-
|
|
1894
|
+
className: "dsh-ui-form-footer dsh-ui-actions-end",
|
|
1788
1895
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1789
1896
|
className: "dsh-ui-meta",
|
|
1790
1897
|
children: limitsDirty || keysDirty ? text.unsaved : text.saveHint
|
|
@@ -1799,85 +1906,30 @@ function NetworkSearchSettings({ client, hidden }) {
|
|
|
1799
1906
|
]
|
|
1800
1907
|
});
|
|
1801
1908
|
}
|
|
1802
|
-
const styles = `${officialUiCss("ws-root")}
|
|
1803
|
-
.ws-root { max-width: 760px; }
|
|
1804
|
-
.ws-card-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding-bottom: 8px; }
|
|
1805
|
-
.ws-sr-only {
|
|
1806
|
-
position: absolute;
|
|
1807
|
-
width: 1px;
|
|
1808
|
-
height: 1px;
|
|
1809
|
-
padding: 0;
|
|
1810
|
-
margin: -1px;
|
|
1811
|
-
overflow: hidden;
|
|
1812
|
-
clip-path: inset(50%);
|
|
1813
|
-
white-space: nowrap;
|
|
1814
|
-
border: 0;
|
|
1815
|
-
}
|
|
1816
|
-
.ws-provider-note { display: flex; align-items: center; gap: 6px; }
|
|
1817
|
-
.web-search-provider { display: grid; gap: 8px; min-width: 0; }
|
|
1818
|
-
.web-search-provider-info { display: grid; gap: 3px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); overflow-wrap: anywhere; }
|
|
1819
|
-
.web-search-provider-heading { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; min-height: 24px; }
|
|
1820
|
-
.web-search-settings a { color: var(--dsw-alias-state-business-primary); font-size: 12px; line-height: 18px; text-underline-offset: 3px; }
|
|
1821
|
-
/* The primitive renders a 32px control in an inline-flex wrapper; a settings
|
|
1822
|
-
* field needs it to fill the column it sits in. */
|
|
1823
|
-
.ws-input { width: 100%; }
|
|
1824
|
-
.web-search-rank { margin: 0; padding: 0; list-style: none; }
|
|
1825
|
-
.web-search-rank li {
|
|
1826
|
-
position: relative;
|
|
1827
|
-
display: grid;
|
|
1828
|
-
grid-template-columns: 24px minmax(0, 1fr) auto;
|
|
1829
|
-
gap: 10px;
|
|
1830
|
-
align-items: start;
|
|
1831
|
-
padding: 14px 0;
|
|
1832
|
-
border-top: 0.5px solid var(--dsw-alias-border-l2);
|
|
1833
|
-
}
|
|
1834
|
-
.web-search-settings button.web-search-drag-handle {
|
|
1835
|
-
display: grid;
|
|
1836
|
-
place-items: center;
|
|
1837
|
-
width: 24px;
|
|
1838
|
-
height: 24px;
|
|
1839
|
-
min-height: 24px;
|
|
1840
|
-
padding: 0;
|
|
1841
|
-
cursor: grab;
|
|
1842
|
-
opacity: 0.65;
|
|
1843
|
-
}
|
|
1844
|
-
.web-search-settings button.web-search-drag-handle:hover { opacity: 1; }
|
|
1845
|
-
.web-search-settings button.web-search-drag-handle:active { cursor: grabbing; }
|
|
1846
|
-
.web-search-settings button.web-search-drag-handle[aria-disabled='true'] { cursor: wait; opacity: 0.4; }
|
|
1847
|
-
.web-search-rank li[data-dragging] { opacity: 0.45; }
|
|
1848
|
-
.web-search-rank li[data-drop]::after { content: ''; position: absolute; left: 0; right: 0; height: 2px; background: var(--dsw-alias-state-business-primary); pointer-events: none; }
|
|
1849
|
-
.web-search-rank li[data-drop='before']::after { top: -1px; }
|
|
1850
|
-
.web-search-rank li[data-drop='after']::after { bottom: -1px; }
|
|
1851
|
-
.web-search-rank-index { color: var(--dsw-alias-label-tertiary); font-variant-numeric: tabular-nums; line-height: 24px; }
|
|
1852
|
-
.web-search-rank-move { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; padding-top: 2px; }
|
|
1853
|
-
.web-search-limits { margin: 0; border: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; }
|
|
1854
|
-
/* A two-column grid, so these fields keep the contract's caption and the
|
|
1855
|
-
* primitive's control and only own their vertical rhythm — a stacked list is
|
|
1856
|
-
* what draws the hairline between fields, and there is nothing to separate. */
|
|
1857
|
-
.ws-limit { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
|
1858
|
-
.ws-danger:hover:not(:disabled),
|
|
1859
|
-
.ws-danger[data-armed] { color: var(--dsw-alias-state-error-primary); border-color: var(--dsw-alias-state-error-primary); }
|
|
1860
|
-
.ws-danger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }
|
|
1861
|
-
@media (max-width: 560px) { .web-search-rank-move { flex-direction: column; align-items: flex-end; } .web-search-limits { grid-template-columns: minmax(0, 1fr); } }
|
|
1862
|
-
`;
|
|
1863
1909
|
function apply(ctx) {
|
|
1864
1910
|
const client = ctx;
|
|
1865
1911
|
ctx.effect(() => {
|
|
1866
1912
|
if (typeof document === "undefined") return () => {};
|
|
1867
1913
|
const style = document.createElement("style");
|
|
1868
1914
|
style.setAttribute("data-plugin", "@klarkxy/dsh-web-search-manager");
|
|
1869
|
-
style.textContent =
|
|
1915
|
+
style.textContent = webSearchClientStyles;
|
|
1870
1916
|
style.dataset.dshWebSearch = "";
|
|
1871
1917
|
document.head.appendChild(style);
|
|
1872
1918
|
return () => style.remove();
|
|
1873
1919
|
}, "web-search-manager.styles");
|
|
1874
|
-
ctx.effect(() => client.slots.inject("
|
|
1875
|
-
name: "
|
|
1876
|
-
|
|
1920
|
+
ctx.effect(() => client.slots.inject("settings.section", () => [client.slots.register({
|
|
1921
|
+
name: "settings.section",
|
|
1922
|
+
id: "web-search-manager",
|
|
1923
|
+
order: 150,
|
|
1924
|
+
label: () => (client.locale?.getSnapshot().active ?? "zh").startsWith("zh") ? "网页搜索" : "Web Search"
|
|
1877
1925
|
}, (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NetworkSearchSettings, {
|
|
1878
1926
|
client,
|
|
1879
1927
|
hidden: props?.hidden
|
|
1880
|
-
}))
|
|
1928
|
+
})), client.slots.inject("settings.section.icon", () => client.slots.register({
|
|
1929
|
+
name: "settings.section.icon",
|
|
1930
|
+
id: "web-search-manager",
|
|
1931
|
+
order: 150
|
|
1932
|
+
}, _deepseek_ai_dsh_client_ui_primitives.IconGlobeOutlineRegular))]), "web-search-manager.settings");
|
|
1881
1933
|
}
|
|
1882
1934
|
//#endregion
|
|
1883
1935
|
exports.NetworkSearchSettings = NetworkSearchSettings;
|