dsh-web-search-plugin 0.3.1 → 0.4.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  本项目的重要变更都记录在此。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
4
4
 
5
+ ## [0.4.1] - 2026-09-10
6
+
7
+ ### 变更
8
+
9
+ - **适配 DeepSeek Harness `0.1.5-rc.1`**:四个 DSH peerDependencies 提升到 `^0.1.5-rc.1`,Node.js 运行要求对齐为 `^22.19.0 || >=24.0.0`。
10
+ - 浏览器端显式注入 `remote.credentials`,避免 API remote 尚未挂载时访问凭据服务的启动顺序竞态。
11
+ - Bundle 覆盖 `web.config` 时保留上游 `fetchProvider: http`,不再因切换搜索 provider 而隐式清除抓取 provider。
12
+ - Brave 的 `proxy` 仅作为 provider 级显式覆盖;留空时继承 DSH 的全局代理分发器,统一支持 `HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY` / `NO_PROXY`。
13
+ - 版本号及 `User-Agent` 更新为 `0.4.1`。
14
+
15
+ ## [0.4.0] - 2026-09-02
16
+
17
+ ### 变更
18
+
19
+ - **适配 DeepSeek Harness 最新 main(`0.1.2-alpha.4`)**:`@deepseek-ai/dsh-settings` 已移除顶层 `installSettingsSection` / `settingsNamespace`,Host 侧改为在 `ctx.inject(['settings'])` 后调用 `settingsCtx.settings.installSection(ctx, ...)`;settings namespace 直接使用普通字符串。
20
+ - **浏览器端移除对 `@deepseek-ai/dsh-client-runtime` / 旧 `connection` 的依赖**:该包已不在最新 Harness workspace / 客户端模块表中。`createSnapshotStore` 改从平台常驻模块 `@deepseek-ai/dsh-client-store` 导入;`dsh.client.inject` 与客户端 `inject` 对齐为 `slots` / `locale` / `remote` / `settingsScope`。
21
+ - **凭据远端接口迁移到 `ctx.remote`**:`credentials.describe(refs[])` / `set(ref, value)` 使用最新 Remote 参数与响应形状(`{ ok, value }`);凭据变更事件从 `credentials/updated` 改为 `credentials/reference-updated`;不再经旧 `connection.api` 调用。
22
+ - peerDependencies 中 dsh 包版本从 `0.1.0-rc.7` 提升到 `0.1.2-alpha.4`;`@deepseek-ai/cordis` / `@deepseek-ai/schemastery` 分别对齐 `^4.0.2` / `^3.18.2`;版本号升至 `0.4.0`,`User-Agent` 同步。
23
+
5
24
  ## [0.3.1] - 2026-08-30
6
25
 
7
26
  ### 修复
@@ -99,7 +118,7 @@
99
118
 
100
119
  ### 修复
101
120
 
102
- - **客户端 bundle 缺少 `exports.inject`**(`lib/client.js`)。浏览器插件原先只导出 `apply`,cordis 的 `fiber.inject` 为空,访问 `ctx.locale` 等服务会抛 `cannot get property "locale" without inject`。现在导出 `inject = ["slots", "locale", "connection", "remote", "settingsScope"]`。
121
+ - **客户端 bundle 缺少 `exports.inject`**(`lib/client.js`)。浏览器插件原先只导出 `apply`,cordis 的 `fiber.inject` 为空,访问 `ctx.locale` 等服务会抛 `cannot get property "locale" without inject`。现在导出 `inject = ["slots", "locale", "remote", "settingsScope"]`。
103
122
  - **插件卡片的 slot 注册**(`lib/client.js`)。卡片按 rc.6 的 `id`/`order` 形状注册进 `settings.plugin.item`;该 slot 从 rc.6+ 起是 keyed 的,必须带 `key: "dsh-web-search-plugin"`。
104
123
  - **`CardForm.field("apiKey")` 崩溃**(`lib/client.js`)。只写凭据字段没有 section spec,对 `undefined` 调用 `spec.format(...)` 会在卡片投影时抛 `Cannot read properties of undefined (reading 'format')`。已加上 secret 字段分支(对齐官方 `CardForm`)。
105
124
  - **`dsh.client.inject` 补上 `@deepseek-ai/dsh-client-ui-slots`**(`package.json`),与社区插件的加载集合一致。
package/README.md CHANGED
@@ -17,19 +17,20 @@
17
17
 
18
18
  ## 特性
19
19
 
20
- - 与官方 `@deepseek-ai/dsh-web-search-deepseek` 相同的提供方约定:`inject: ['web']` + `installSettingsSection` + `ctx.web.registerSearchProvider`。
20
+ - 与官方 `@deepseek-ai/dsh-web-search-deepseek` 相同的提供方约定:`inject: ['web']` + `ctx.settings.installSection` + `ctx.web.registerSearchProvider`。
21
21
  - 顶层 **设置 → 网页搜索** 分区:两列布局、未保存草稿、保存 toast;结果数量为 1–20 下拉。
22
22
  - **默认引擎为 DeepSeek(官方)**:新装 / 未显式改动时,搜索直接走 `deepseek-official`,不再依赖 keyless 的 Tavily。
23
23
  - 纯 REST 后端由**静态元数据表 + 通用后端**驱动,新增 provider 即"表里加一行 + 官方跳转链接",无定制执行代码。
24
24
  - Tavily keyless 无需密钥即可用;Brave 需要订阅 token(若本机已有 `BRAVE_API_KEY` 凭据,可直接复用)。
25
25
  - Tavily keyed / Brave 在设置卡展示额度进度条(DeepSeek 官方与 Tavily keyless / 其余 REST 后端不展示)。
26
26
  - 各引擎结果都规范化为接缝的 `WebSearchResult`(可选 `content` + `sources[]`),按 URL 去重。
27
- - 设置段 `dsh-web-search-plugin` 通过 rc.7 的 `settings.describe()` 动态暴露,不需要宿主白名单补丁,也不需要自建回环 settings 桥。
27
+ - 设置段 `dsh-web-search-plugin` 通过 dsh 的 `settings.installSection` 注册、由 `settings.describe()` 动态暴露,不需要宿主白名单补丁,也不需要自建回环 settings 桥。
28
28
  - 错误映射为 `WEB_PROVIDER_ERROR` / `WEB_ABORTED` / `WEB_PROVIDER_CREDENTIAL_MISSING`。
29
29
 
30
30
  ## 运行要求
31
31
 
32
- - DeepSeek Harness `0.1.0-rc.7` 或更新
32
+ - DeepSeek Harness `0.1.5-rc.1` 或兼容版本
33
+ - Node.js `^22.19.0` 或 `>=24.0.0`
33
34
  - pnpm,用于通过 `dsh plugin` 把插件装进 profile
34
35
 
35
36
  ## 安装
@@ -72,7 +73,7 @@ dsh plugin --profile web add dsh-web-search-plugin
72
73
  | `country` | — | Brave 的 `country`(ISO 两位码,如 `cn`);留空使用 Brave 默认 |
73
74
  | `searchLang` | — | Brave 的 `search_lang`(如 `zh-hans`);留空使用 Brave 默认 |
74
75
  | `freshness` | — | Brave 的 `freshness`:`pd` / `pw` / `pm` / `py` |
75
- | `proxy` | — | Brave 使用的 HTTP(S) 代理;留空回退 `HTTPS_PROXY` / `HTTP_PROXY` |
76
+ | `proxy` | — | Brave 使用的 HTTP(S) 代理覆盖;留空继承 DSH 的全局 `HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY` / `NO_PROXY` 策略 |
76
77
  | `serperApiKey` / `serperApiKeyEnv` / `serperBaseURL` | — / `SERPER_API_KEY` / — | Serper 的 key 字面量 / 凭据引用名 / 端点覆盖 |
77
78
  | `serpapiApiKey` / `serpapiApiKeyEnv` / `serpapiBaseURL` | — / `SERPAPI_API_KEY` / — | SerpApi 的 key 字面量 / 凭据引用名 / 端点覆盖 |
78
79
  | `exaApiKey` / `exaApiKeyEnv` / `exaBaseURL` | — / `EXA_API_KEY` / — | Exa 的 key 字面量 / 凭据引用名 / 端点覆盖 |
@@ -189,7 +190,7 @@ dsh plugin --profile web remove @dsh-ltctfer/dsh-web-search-brave
189
190
  npm run check
190
191
  ```
191
192
 
192
- 客户端 bundle 必须保持 `window.__ModuleLoader__.load({ id, factory })` 线格式 — 由 `dsh-client-modules` 加载,不是打包器。必须同时导出 `apply` 和 `inject`(`slots`、`locale`、`connection`、`remote`、`settingsScope`),并把分区注册进 `settings.section`(`id: "web-search"`)。
193
+ 客户端 bundle 必须保持 `window.__ModuleLoader__.load({ id, factory })` 线格式 — 由 `dsh-client-modules` 加载,不是打包器。必须同时导出 `apply` 和 `inject`(`slots`、`locale`、`remote`、`settingsScope`),并把分区注册进 `settings.section`(`id: "web-search"`)。
193
194
 
194
195
  ## 发布
195
196
 
package/cordis.patch.yml CHANGED
@@ -3,14 +3,16 @@
3
3
  # installs the package as a plain library: no loader row, no Host apply, no
4
4
  # `/plugins/<name>/client.js`.
5
5
  #
6
- # `searchProvider` is restated in full because a Cordis patch replaces the
7
- # targeted row's whole `config`. The profile's own cordis.patch.yml still
8
- # wins if it later overrides `web`. The seam id is `dsh-web-search`; the
9
- # backend (DeepSeek / Tavily / Brave) is the plugin's own `provider` setting.
6
+ # `searchProvider` and the upstream `fetchProvider` are restated in full
7
+ # because a Cordis patch replaces the targeted row's whole `config`. The
8
+ # profile's own cordis.patch.yml still wins if it later overrides `web`. The
9
+ # seam id is `dsh-web-search`; the backend (DeepSeek / Tavily / Brave) is the
10
+ # plugin's own `provider` setting.
10
11
  - id: web
11
12
  name: '@deepseek-ai/dsh-web'
12
13
  config:
13
14
  searchProvider: dsh-web-search
15
+ fetchProvider: http
14
16
 
15
17
  # This plugin re-hosts the DeepSeek backend, so the in-box DeepSeek host
16
18
  # plugin is redundant: disabling it removes its `deepseek-official` provider
package/lib/brave.js CHANGED
@@ -12,7 +12,6 @@
12
12
  */
13
13
  import { ProxyAgent } from "undici";
14
14
  import { WebError } from "@deepseek-ai/dsh-web";
15
- import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
16
15
  import { MAX_RESULTS_CAP, USER_AGENT, isAbortError, isPositiveInteger, resolveApiKey, resolveSecret, searchAborted, throwIfSearchAborted } from "./shared.js";
17
16
 
18
17
  /** Default Brave Search API web-results endpoint. */
@@ -123,9 +122,9 @@ export class BraveSearchProvider {
123
122
  }
124
123
 
125
124
  /**
126
- * Cached undici ProxyAgent for the current proxy URL. Node's fetch does not
127
- * read `HTTPS_PROXY` itself; a configured proxy (or the launch-environment
128
- * fallback) is how DNS for api.search.brave.com can go through a tunnel.
125
+ * Cached undici ProxyAgent for an explicit provider-level proxy override.
126
+ * With no override, fetch inherits the dispatcher installed by DSH so its
127
+ * HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY policy remains intact.
129
128
  */
130
129
  dispatcher(options) {
131
130
  const proxy = options.proxy;
@@ -142,7 +141,6 @@ export class BraveSearchProvider {
142
141
 
143
142
  /** Project the plugin section into Brave backend options. */
144
143
  export function resolveBraveOptions(ctx, config) {
145
- const environment = launchEnvironmentOf(ctx);
146
144
  return {
147
145
  ...resolveSecret(ctx, {
148
146
  literal: config.braveApiKey,
@@ -153,6 +151,6 @@ export function resolveBraveOptions(ctx, config) {
153
151
  country: config.country,
154
152
  searchLang: config.searchLang,
155
153
  freshness: config.freshness,
156
- proxy: config.proxy ?? environment.get("HTTPS_PROXY")?.value ?? environment.get("HTTP_PROXY")?.value
154
+ proxy: config.proxy
157
155
  };
158
156
  }
package/lib/client.js CHANGED
@@ -21,7 +21,7 @@ window.__ModuleLoader__.load({
21
21
  var exports = module.exports;
22
22
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
23
23
  let react = require("react");
24
- let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
24
+ let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
25
25
 
26
26
  /** Settings namespace of this plugin. */
27
27
  const NS = "dsh-web-search-plugin";
@@ -132,7 +132,7 @@ window.__ModuleLoader__.load({
132
132
  freshnessMonth: "Past month",
133
133
  freshnessYear: "Past year",
134
134
  proxy: "Proxy",
135
- proxyPlaceholder: "Leave blank to use HTTPS_PROXY / HTTP_PROXY.",
135
+ proxyPlaceholder: "Leave blank to inherit the DSH proxy settings.",
136
136
  deepseekApiKeyEnv: "Credential reference",
137
137
  deepseekApiKeyEnvHint: "Name of the credential/env var resolved for DeepSeek search.",
138
138
  deepseekBaseURL: "Endpoint",
@@ -228,7 +228,7 @@ window.__ModuleLoader__.load({
228
228
  freshnessMonth: "过去一月",
229
229
  freshnessYear: "过去一年",
230
230
  proxy: "代理",
231
- proxyPlaceholder: "留空使用 HTTPS_PROXY / HTTP_PROXY环境变量",
231
+ proxyPlaceholder: "留空继承 DSH 全局代理设置",
232
232
  deepseekApiKeyEnv: "凭据引用名",
233
233
  deepseekApiKeyEnvHint: "DeepSeek 搜索解析的凭据/环境变量名。",
234
234
  deepseekBaseURL: "接口地址",
@@ -334,9 +334,9 @@ window.__ModuleLoader__.load({
334
334
  * spec and are written through the credentials domain.
335
335
  */
336
336
  var SearchCardForm = class {
337
- constructor(scope, api) {
337
+ constructor(scope, remote) {
338
338
  this.scope = scope;
339
- this.api = api;
339
+ this.remote = remote;
340
340
  this.specs = new Map([
341
341
  choiceField("provider"),
342
342
  choiceField("mode"),
@@ -391,7 +391,7 @@ window.__ModuleLoader__.load({
391
391
  this.readCredential();
392
392
  }
393
393
  bind(project) {
394
- const store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(project());
394
+ const store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(project());
395
395
  this.listeners.add(() => {
396
396
  store.set(project());
397
397
  });
@@ -591,12 +591,12 @@ window.__ModuleLoader__.load({
591
591
  }
592
592
  let response;
593
593
  try {
594
- response = await this.api.credentials.describe({ refs: [ref] });
594
+ response = await this.remote.credentials.describe([ref]);
595
595
  } catch (_credentialReadFailure) {
596
596
  return;
597
597
  }
598
- if (!response.result.ok || ref !== this.refOf()) return;
599
- const view = response.result.value.credentials[ref];
598
+ if (!response.ok || ref !== this.refOf()) return;
599
+ const view = response.value[ref];
600
600
  const next = {
601
601
  ref,
602
602
  configured: view?.configured ?? false,
@@ -619,7 +619,8 @@ window.__ModuleLoader__.load({
619
619
  ref = rest !== void 0 ? this.restKeyRef(rest) : this.tavilyRef();
620
620
  }
621
621
  try {
622
- await this.api.credentials.set({ ref, value });
622
+ const response = await this.remote.credentials.set(ref, value);
623
+ if (!response.ok) return false;
623
624
  } catch (_credentialWriteFailure) {}
624
625
  await this.readCredential();
625
626
  return this.credential.ref === ref ? this.credential.configured : true;
@@ -628,10 +629,10 @@ window.__ModuleLoader__.load({
628
629
 
629
630
  /** Bridges the plugin scope and the credentials domain onto the card. */
630
631
  var SearchCardController = class {
631
- constructor(scope, api) {
632
+ constructor(scope, remote) {
632
633
  this.scope = scope;
633
- this.api = api;
634
- this.form = new SearchCardForm(scope, api);
634
+ this.remote = remote;
635
+ this.form = new SearchCardForm(scope, remote);
635
636
  this.store = this.form.bind(() => this.projection());
636
637
  scope.subscribe(() => {
637
638
  this.form.readCredential();
@@ -1150,11 +1151,10 @@ window.__ModuleLoader__.load({
1150
1151
 
1151
1152
  /** Mount the top-level "Web search" settings section. */
1152
1153
  function apply(ctx) {
1153
- const { api } = ctx.get("connection");
1154
1154
  const t = ctx.locale.bind(NS);
1155
1155
  ctx.effect(() => ctx.locale.register(NS, { zh, en }), "dsh-web-search-plugin: card dictionaries");
1156
- const controller = new SearchCardController(ctx.settingsScope.bind({ namespace: NS }), api);
1157
- ctx.effect(() => ctx.remote.$on("credentials/updated", (ref) => {
1156
+ const controller = new SearchCardController(ctx.settingsScope.bind({ namespace: NS }), ctx.remote);
1157
+ ctx.effect(() => ctx.remote.$on("credentials/reference-updated", (ref) => {
1158
1158
  controller.form.refreshCredential(ref);
1159
1159
  }), "dsh-web-search-plugin: credential invalidations");
1160
1160
  ctx.effect(() => usageStore.start(), "dsh-web-search-plugin: usage poll");
@@ -1168,7 +1168,7 @@ window.__ModuleLoader__.load({
1168
1168
  }, makeSection(ctx, controller)));
1169
1169
  }
1170
1170
 
1171
- const inject = ["slots", "locale", "connection", "remote", "settingsScope"];
1171
+ const inject = ["slots", "locale", "remote", "remote.credentials", "settingsScope"];
1172
1172
 
1173
1173
  exports.apply = apply;
1174
1174
  exports.inject = inject;
package/lib/index.js CHANGED
@@ -17,8 +17,6 @@
17
17
  * @module dsh-web-search-plugin
18
18
  */
19
19
  import z from "@deepseek-ai/schemastery";
20
- import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
21
- import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
22
20
  import { MAX_RESULTS_CAP } from "./shared.js";
23
21
  import { TAVILY_DEFAULT_API_KEY_ENV, TAVILY_DEFAULT_BASE_URL, TavilySearchProvider, resolveTavilyOptions } from "./tavily.js";
24
22
  import { BRAVE_DEFAULT_API_KEY_ENV, BRAVE_DEFAULT_BASE_URL, BraveSearchProvider, resolveBraveOptions } from "./brave.js";
@@ -34,6 +32,8 @@ const SEARCH_PROVIDER_ID = "dsh-web-search";
34
32
  const name = "dsh-web-search-plugin";
35
33
  /** The web seam this provider registers into. */
36
34
  const inject = ["web"];
35
+ /** Settings namespace carrying this plugin's backend switch and options. */
36
+ const WEB_SEARCH_SETTINGS_NAMESPACE = "dsh-web-search-plugin";
37
37
 
38
38
  /** Plugin config (all optional — `apply` fills defaults). */
39
39
  const Config = z.object({
@@ -67,7 +67,7 @@ const Config = z.object({
67
67
  searchLang: z.string().default(""),
68
68
  /** Optional Brave `freshness` (`pd` / `pw` / `pm` / `py`). */
69
69
  freshness: z.string().default(""),
70
- /** Optional HTTP(S) proxy URL for Brave (falls back to HTTPS_PROXY / HTTP_PROXY). */
70
+ /** Optional HTTP(S) proxy URL for Brave; blank inherits DSH's global proxy policy. */
71
71
  proxy: z.string().default(""),
72
72
  /** Literal Serper API key; prefer {@link serperApiKeyEnv}. */
73
73
  serperApiKey: z.string().role("secret").default(""),
@@ -117,11 +117,6 @@ const Config = z.object({
117
117
  maxUses: z.number().step(1).min(1).default(5)
118
118
  });
119
119
 
120
- /** Settings namespace carrying this plugin's backend switch and options. */
121
- const WEB_SEARCH_SETTINGS_NAMESPACE = settingsNamespace("dsh-web-search-plugin");
122
- /** @deprecated Use {@link WEB_SEARCH_SETTINGS_NAMESPACE}. */
123
- const WEB_SEARCH_TAVILY_SETTINGS_NAMESPACE = WEB_SEARCH_SETTINGS_NAMESPACE;
124
-
125
120
  /**
126
121
  * One seam-facing provider whose `id` stays `dsh-web-search`. The active
127
122
  * backend is read from the live settings section on every `available` /
@@ -177,7 +172,7 @@ function resolveOptions(ctx, config) {
177
172
  // metadata row's default is not enough (self-hosted SearXNG, proxied
178
173
  // providers, custom key refs).
179
174
  const keySourceByProvider = {
180
- brave: { literal: config.braveApiKey, envName: config.braveApiKeyEnv ?? BRAVE_DEFAULT_API_KEY_ENV, baseURL: config.braveBaseURL ?? "", proxy: config.proxy || launchEnvironmentOf(ctx).get("HTTPS_PROXY")?.value || launchEnvironmentOf(ctx).get("HTTP_PROXY")?.value || "" },
175
+ brave: { literal: config.braveApiKey, envName: config.braveApiKeyEnv ?? BRAVE_DEFAULT_API_KEY_ENV, baseURL: config.braveBaseURL ?? "", proxy: config.proxy ?? "" },
181
176
  tavily: { literal: config.apiKey, envName: config.apiKeyEnv ?? TAVILY_DEFAULT_API_KEY_ENV, baseURL: config.baseURL ?? "" },
182
177
  serper: { literal: config.serperApiKey, envName: config.serperApiKeyEnv ?? "SERPER_API_KEY", baseURL: config.serperBaseURL ?? "" },
183
178
  serpapi: { literal: config.serpapiApiKey, envName: config.serpapiApiKeyEnv ?? "SERPAPI_API_KEY", baseURL: config.serpapiBaseURL ?? "" },
@@ -254,11 +249,13 @@ function sendJson(res, statusCode, data) {
254
249
  /** Register the dispatched search provider with `ctx.web`. */
255
250
  function apply(ctx, config) {
256
251
  let current = () => config;
257
- installSettingsSection(ctx, WEB_SEARCH_SETTINGS_NAMESPACE, Config, config, {
258
- setSource: (source) => {
259
- current = source;
260
- },
261
- onChange: () => {}
252
+ ctx.inject(["settings"], (settingsCtx) => {
253
+ settingsCtx.settings.installSection(ctx, WEB_SEARCH_SETTINGS_NAMESPACE, Config, config, {
254
+ setSource: (source) => {
255
+ current = source;
256
+ },
257
+ onChange: () => {}
258
+ });
262
259
  });
263
260
  const live = () => resolveOptions(ctx, current());
264
261
  const usage = new UsageTracker({
@@ -335,7 +332,6 @@ export {
335
332
  TavilySearchProvider,
336
333
  UsageTracker,
337
334
  WEB_SEARCH_SETTINGS_NAMESPACE,
338
- WEB_SEARCH_TAVILY_SETTINGS_NAMESPACE,
339
335
  apply,
340
336
  findProvider,
341
337
  inject,
package/lib/shared.js CHANGED
@@ -7,7 +7,7 @@ import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
7
7
  import { WebError } from "@deepseek-ai/dsh-web";
8
8
 
9
9
  /** Attribution header sent on every request. */
10
- export const USER_AGENT = "dsh-web-search-plugin/0.3.1";
10
+ export const USER_AGENT = "dsh-web-search-plugin/0.4.1";
11
11
  /** Shared cap: Tavily `max_results` and Brave `count` both accept 1..20. */
12
12
  export const MAX_RESULTS_CAP = 20;
13
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-web-search-plugin",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Unified web search for the DeepSeek Harness seam (ctx.web): DeepSeek (official), Tavily, Brave, Serper, SerpApi, Exa, SearXNG, Scavio, and Firecrawl backends",
5
5
  "keywords": [
6
6
  "dsh-plugin",
@@ -24,7 +24,7 @@
24
24
  "LICENSE"
25
25
  ],
26
26
  "engines": {
27
- "node": ">=18"
27
+ "node": "^22.19.0 || >=24.0.0"
28
28
  },
29
29
  "exports": {
30
30
  ".": {
@@ -43,9 +43,7 @@
43
43
  "client": {
44
44
  "platform": "web",
45
45
  "inject": [
46
- "@deepseek-ai/dsh-client-connection",
47
46
  "@deepseek-ai/dsh-client-locale",
48
- "@deepseek-ai/dsh-client-runtime",
49
47
  "@deepseek-ai/dsh-client-ui-settings",
50
48
  "@deepseek-ai/dsh-client-ui-slots",
51
49
  "@deepseek-ai/dsh-api-remotes"
@@ -59,12 +57,12 @@
59
57
  "undici": "^6.21.0"
60
58
  },
61
59
  "peerDependencies": {
62
- "@deepseek-ai/dsh-web": "^0.1.0-rc.7",
63
- "@deepseek-ai/dsh-credentials": "^0.1.0-rc.7",
64
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.7",
65
- "@deepseek-ai/dsh-launch-environment": "^0.1.0-rc.7",
66
- "@deepseek-ai/schemastery": "^3.18.1",
67
- "@deepseek-ai/cordis": "^4.0.1"
60
+ "@deepseek-ai/dsh-web": "^0.1.5-rc.1",
61
+ "@deepseek-ai/dsh-credentials": "^0.1.5-rc.1",
62
+ "@deepseek-ai/dsh-settings": "^0.1.5-rc.1",
63
+ "@deepseek-ai/dsh-launch-environment": "^0.1.5-rc.1",
64
+ "@deepseek-ai/schemastery": "^3.18.2",
65
+ "@deepseek-ai/cordis": "^4.0.2"
68
66
  },
69
67
  "license": "MIT",
70
68
  "repository": {