@240xu/dsh-websearch 2.7.2 → 2.7.3

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 CHANGED
@@ -115,6 +115,14 @@ pnpm install
115
115
 
116
116
  环境变量兜底:未在 credentials 配置时回退读同名环境变量;`DSH_UNIFIED_SEARCH_BACKENDS` 可逗号分隔强制指定启用集合。
117
117
 
118
+ ## v2.7.3 兼容修复 | What's new in v2.7.3
119
+
120
+ - **DSH 0.1.7 客户端兼容(P0)**:settingsScope 客户端服务在 0.1.7 被移除;现改为 feature-detect——0.1.5(或装 dsh-settings-scope-shim)行为不变,0.1.7 无 shim 时设置卡片优雅停用(console.warn 指引),客户端不再静默全死。
121
+ - **DSH 0.1.7 服务端(P1)**:SettingsForms 无 installSection,原 typeof 守卫静默跳过;现输出一次性 console.warn(搜索功能经 cordis config 不受影响),SettingsForms 迁移已立牌。
122
+ - **engines**:声明 `node >= 20.3`(AbortSignal.any 实测需求,Node 18/20.0-20.2 首次搜索即 TypeError)。
123
+ - description 瘦身(版本历史移回本文件/CHANGELOG.md)。
124
+ - **Windows 双端(P2)**:缓存/历史目录回退改用 `os.homedir()`(此前 `process.env.HOME` 在 Windows 通常未设 → 相对路径 → 缓存静默失效)。
125
+
118
126
  ## v2.7.2 补丁 | What's new in v2.7.2
119
127
 
120
128
  - 设置项 label:6 个新设置项在 schema 层挂用户语言 label(含单位尾注,如「缓存有效期(秒)」),宿主渲染不再回退 camelCase 键名;description 同步以人话名称开头(真机渲染行为归视觉待办 V5)。
package/lib/client.js CHANGED
@@ -543,10 +543,23 @@ window.__ModuleLoader__.load({
543
543
  ] });
544
544
  }
545
545
 
546
- /** Plugin entry: register the card into the settings plugins page. */
546
+ /**
547
+ * Plugin entry: register the card into the settings plugins page.
548
+ * Compatibility (compat-audit P0): the settingsScope client service was
549
+ * removed in DSH 0.1.7. It stays in `inject` so the fiber still
550
+ * activates when the shim supplies it; every access is feature-detected.
551
+ */
547
552
  const inject = ["slots", "locale", "connection", "remote", "settingsScope"];
548
553
  function apply(ctx) {
549
554
  ctx.effect(() => ctx.locale.register(NS, { zh, en }), "websearch: copy dictionaries");
555
+ const hasSettingsScope = ctx.get("settingsScope") !== undefined && typeof ctx.settingsScope?.bind === "function";
556
+ if (!hasSettingsScope) {
557
+ // DSH >= 0.1.7 without dsh-settings-scope-shim: the settings card
558
+ // cannot bind its scope. Stop wiring the card instead of hard-
559
+ // crashing the client fiber; the breadcrumb aids diagnosis.
560
+ console.warn("[dsh-websearch] settingsScope service unavailable (DSH >= 0.1.7); unified-search settings card disabled. Configure via server settings/cordis config or install dsh-settings-scope-shim.");
561
+ return;
562
+ }
550
563
  const controller = new UnifiedSearchCardController(
551
564
  ctx.settingsScope.bind({ namespace: PLUGIN_NS }),
552
565
  ctx.get("connection"),
package/lib/index.js CHANGED
@@ -38,6 +38,7 @@ import { registerHealthRoute } from "./health.js";
38
38
  import { createSearchCache, CACHE_DEFAULTS } from "./cache.js";
39
39
  import { createHistoryStore, registerHistoryRoutes, HISTORY_MAX_ENTRIES } from "./history.js";
40
40
  import { BREAKER_DEFAULTS } from "./breaker.js";
41
+ import os from "node:os";
41
42
  import path from "node:path";
42
43
 
43
44
  /** Cordis plugin name used by loader diagnostics. */
@@ -334,6 +335,19 @@ export function resolveOptions(ctx, config) {
334
335
  };
335
336
  }
336
337
 
338
+ /**
339
+ * Resolve the plugin's persistent store directory (cache + history).
340
+ * Pure and exported for tests: precedence is DSH_HOME > <home>/.dsh, where
341
+ * home falls back to os.homedir() — NOT process.env.HOME, which is usually
342
+ * unset on Windows and would silently disable cache/history (compat-audit
343
+ * P2-7).
344
+ * @param {{DSH_HOME?: string, HOME?: string}} env
345
+ * @param {string} [fallbackHome] injected os.homedir() for tests
346
+ */
347
+ export function resolveStoreDir(env = process.env, fallbackHome = os.homedir()) {
348
+ return path.join(env.DSH_HOME || path.join(fallbackHome, ".dsh"), "cache", "websearch");
349
+ }
350
+
337
351
  /**
338
352
  * Register the unified search provider with ctx.web. Installs a settings
339
353
  * section so users can configure enabled backends / numResults / base URLs /
@@ -343,22 +357,35 @@ export function apply(ctx, config) {
343
357
  let current = () => config;
344
358
 
345
359
  ctx.inject(["settings"], (settingsCtx) => {
346
- if (typeof settingsCtx.settings?.installSection !== "function") return;
347
- settingsCtx.settings.installSection(ctx, NAMESPACE, Config, config, {
348
- setSource: (source) => {
349
- current = source;
350
- },
351
- onChange: () => {},
352
- });
360
+ const settings = settingsCtx.settings;
361
+ if (typeof settings?.installSection === "function") {
362
+ settings.installSection(ctx, NAMESPACE, Config, config, {
363
+ setSource: (source) => {
364
+ current = source;
365
+ },
366
+ onChange: () => {},
367
+ });
368
+ return;
369
+ }
370
+ // DSH 0.1.7+: the settings service is SettingsForms and has no
371
+ // installSection. The Config schema still resolves through cordis config
372
+ // (this file reads `current()`), so search keeps working; surface the gap
373
+ // once instead of silently swallowing it (compat-audit P1).
374
+ console.warn(
375
+ "[dsh-websearch] settings service has no installSection (DSH >= 0.1.7 SettingsForms line); " +
376
+ "the Settings panel section is not installed. Configure the unified-search namespace via cordis config " +
377
+ "or the client settings card; migration to the SettingsForms API is tracked for a future release.",
378
+ );
353
379
  });
354
380
 
355
381
  // v2.7.0 stores: disk cache + append-only search history, both under
356
382
  // DSH_HOME/cache/websearch (created lazily; every fs error is swallowed so
357
383
  // a broken store never breaks a search).
358
- const storeDir = path.join(
359
- process.env.DSH_HOME || path.join(process.env.HOME || "", ".dsh"),
360
- "cache", "websearch",
361
- );
384
+ // DSH_HOME wins when set; otherwise the OS home directory. os.homedir()
385
+ // (not process.env.HOME) is the cross-platform fallback — HOME is usually
386
+ // unset on Windows, which previously made storeDir relative to the current
387
+ // working directory and silently disabled cache/history (compat-audit P2-7).
388
+ const storeDir = resolveStoreDir();
362
389
  const searchCache = createSearchCache({
363
390
  dir: path.join(storeDir, "results"),
364
391
  ttlMs: () => resolveOptions(ctx, current()).cacheTtlS * 1000,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@240xu/dsh-websearch",
3
- "version": "2.7.2",
4
- "description": "Unified web search provider for DeepSeek Harness (ctx.web): 11 backends — Exa + Parallel + DDG + SearXNG (keyless), DeepSeek + Anthropic + OpenAI + Brave + Tavily + Serper + Mojeek (key-gated via Settings credentials). Registers provider id \"unified\" for zero-config web_search tool. v2.7.0: disk result cache, per-backend circuit breaker, append-only search history API. v2.7.1 review fixes: cache key includes enabledBackends, scheme whitelist on cache-hit path, serialized history writes, trust fence on /api/websearch/* routes, cooldownMs=0 disables breaker window, user-language settings labels.",
3
+ "version": "2.7.3",
4
+ "description": "Unified web search provider for DeepSeek Harness (ctx.web): 11 backends — Exa + Parallel + DDG + SearXNG (keyless), DeepSeek + Anthropic + OpenAI + Brave + Tavily + Serper + Mojeek (key-gated via Settings credentials). Registers provider id \"unified\" for zero-config web_search. 统一网页搜索聚合:11 后端并发扇出、去重合并,零依赖。See CHANGELOG.md for version history.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -66,5 +66,8 @@
66
66
  ],
67
67
  "platform": "web"
68
68
  }
69
+ },
70
+ "engines": {
71
+ "node": ">=20.3"
69
72
  }
70
73
  }