dsh-web-search-ddg
aooyoo
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web seam — local headless browser, no API key, no m…
PROJECT TOPICS
PROJECT README
English | 中文
A permanent Cordis plugin for the DeepSeek Harness Web GUI that auto-checks for new DeepSeek Harness releases AND installed third-party plugin updates (the former standalone dsh-plugin-checker was merged in v1.1.0), asks the user, and one-click updates with success/failure feedback.
Full update lifecycle — check, backup, update, and restart, all in one plugin.
Main program check — compares the installed @deepseek-ai/dsh version against the npm latest (semver-aware, pre-release handled).
Third-party plugin check — scans installed non-official plugins (composition rows + dsh manifest, layout-agnostic) and compares each against npm latest.
In-GUI banner — locale-aware (zh/en follows the DSH UI language), states update / up-to-date / failure, with a "don't remind me" suppression flag.
One-click update with safety — backs up the deployment lockfile + @deepseek-ai version manifests before installing, so a failed upgrade can be rolled back; plugin updates install in a temp dir and copy in (never touches unrelated packages in profiles/node_modules).
Restart with watchdog — restarts the dsh web service via a detached watchdog script (kills the port listener, relaunches the launcher, retries until the port recovers).
Zero-config portability — profile dir / $DSH_HOME / composition file are derived from the plugin's own install location; the deployment root is resolved via junction realpath with DSH_DEPLOY_ROOT / process.cwd() fallback. Works on any machine without editing code.
Host half (lib/index.js) registers HTTP routes:
GET /dsh-update-checker/status.json — fetches the latest @deepseek-ai/dsh version from the npm registry, reads the locally installed version (from the deployment's node_modules), compares them with semver semantics, and returns a JSON status (including the persisted suppressUpToDate flag).POST /dsh-update-checker/suppress — persists the "don't remind me again" flag for the up-to-date banner (requires { "confirm": true }).POST /dsh-update-checker/update — complete update: backs up the deployment lockfile + @deepseek-ai version manifests, runs npm install @deepseek-ai/dsh@latest in the deployment root, then defensively syncs changed @deepseek-ai packages into $DSH_HOME/profiles/node_modules (skipped for junction-linked packages, which the running Web app resolves through). Requires { "confirm": true }; supports { "dry": true } to preview without executing.POST /dsh-update-checker/restart — restarts the dsh web service (spawns a PowerShell helper that kills the port listener and relaunches <deploy-root>/start-dsh.cmd; the port and launcher path are derived at runtime). Requires { "confirm": true }.GET /dsh-update-checker/plugins.json — scans installed third-party (non-builtin) plugins (composition rows + dsh field, layout-agnostic), compares each against npm latest (semver), returns update status.POST /dsh-update-checker/plugin-update — updates one plugin via temp-dir npm install + copy (never touches other packages in profiles/node_modules, junction-aware, backs up the old version first). Requires { "confirm": true, "name" }.Client half (lib/client.js) is a web module (ModuleLoader format) that registers two cells in the root-scoped shell.overlay slot:
installed → latest) with single / update-all buttons and per-plugin success/failure feedback.
On page load both check once, then re-check every 6 hours.The banner follows the DSH UI language through the client locale service (@deepseek-ai/dsh-client-locale): zh → 中文, en → English, and only those two are shipped — any other locale falls back to Chinese. Switching DSH's language (Settings → General → Language) updates the banner text instantly without a reload. If the locale service is absent from the composition, the client falls back to the Chinese dictionary.
The package is a profile bundle (its manifest declares dsh.bundle.patch).
# 1) put the package into $DSH_HOME/profiles/node_modules/ so the profile can resolve it.
# ⚠️ Do NOT run `npm install` directly inside $DSH_HOME/profiles — it has no
# package.json and npm would prune the entire node_modules (data loss).
#
# Safe option A — install in a temp dir, then copy only this package:
npm i dsh-update-checker --prefix <temp-dir> --no-save
cp -r <temp-dir>/node_modules/dsh-update-checker $DSH_HOME/profiles/node_modules/
#
# Safe option B — copy the package directory manually (from a git clone or tarball).
# 2) add the row to $DSH_HOME/profiles/web/cordis.patch.yml
# $DSH_HOME/profiles/web/cordis.patch.yml
- insert:
- id: dsh-update-checker
name: 'dsh-update-checker'
Then let patch HMR apply it (or restart dsh web) and reload the page.
Step-by-step guide with troubleshooting (中文): docs/INSTALL.md.
All paths are auto-detected at runtime — nothing is hardcoded, so the same package works on any machine:
$DSH_HOME/profiles/node_modules): derived from the plugin's own install location (import.meta.url), walking up to the enclosing node_modules. No configuration needed.$DSH_HOME: derived as the parent of the profiles root (state file, backups, and restart log all live there).cordis.patch.yml): defaults to $DSH_HOME/profiles/web/cordis.patch.yml; if absent, any other cordis.patch.yml under $DSH_HOME/profiles/ containing the plugin id is used.profiles/node_modules/@deepseek-ai/dsh is a junction (the common "save C-drive" setup), realpath() yields <deploy-root>/node_modules/@deepseek-ai/dsh, so the deployment root is derived automatically.DSH_DEPLOY_ROOT, then process.cwd() (launchers usually cd into the deployment directory). To point elsewhere, set DSH_DEPLOY_ROOT or append to DEPLOY_ROOT_CANDIDATES at the top of lib/index.js.start-dsh.cmd, 启动 dsh.bat, start-dsh.bat, …) under the detected deployment root; the web port is read from the running webServer.port. No machine-specific paths are hardcoded in the restart flow.$DSH_HOME — machine-independent.taskkill + a .cmd/.bat launcher script) and the watchdog script is PowerShell.npm install -g @deepseek-ai/dsh@latest (with --allow-scripts for the native-dependency packages). This is correct when @deepseek-ai/dsh is installed globally (the setup this plugin was developed on). On a deployment where dsh lives in a local node_modules (not -g), the update command must be adapted — and must not be run as a plain npm install in the deployment root, because npm may treat the existing packages as extraneous and prune them.{ "confirm": true } so a stray request cannot trigger an install or a restart.package-lock.json + both @deepseek-ai version manifests) is written to $DSH_HOME/dsh-update-checker-backups/<timestamp>/ before npm install runs, so a failed upgrade can be rolled back.runSync failing to copy newly-added @deepseek-ai packages (a missing profile dir made realpath throw ENOENT and abort the sync); fix parseGhRepo truncating repository names that contain dots. Add integration tests that simulate real-copy and junction deployment layouts in a temp dir (via the DSH_UC_PROFILE_NODE_MODULES hook) covering eco-version reads, sync planning, sync execution, backup, and deploy-root detection. All tests run with npm test (30 assertions + host apply() smoke test).repository field and query api.github.com/releases/latest, cross-verify against npm (target version = the higher of the two, GitHub preferred as download source on ties), support plugins that exist only on GitHub (download via codeload tarball, backup + replace), show the update source ([GH] / [GH/npm]) in settings. If GitHub is unreachable it silently falls back to npm; if both sources fail the plugin reports a combined error (timeout included). Adds fetch timeouts (20s queries / 120s download).npm install -g @deepseek-ai/dsh@latest with --allow-scripts for the five native-dependency packages (npm 11 requirement), invoked through process.execPath + the bundled npm-cli.js (no PATH dependence). Fixes the previous non--g npm install which, on machines where dsh is installed globally (global prefix without a package.json), would treat the whole global node_modules as extraneous and prune it.$DSH_HOME, composition file, deploy root, restart launcher) from the plugin's own install location; merge the former standalone dsh-plugin-checker plugin-update capability.lib/index.js — Host half: plain ESM, depends only on Node built-ins. No build step. The pure helpers (parseVersion, compareVersions, tagToVersion, parseGhRepo, planSyncFromMaps, extractTarGzToDir, truncate) are exported as named ESM exports for unit testing.lib/client.js — Client half: plain JS, window.__ModuleLoader__ format, requires only react. No build step.npm test (alias for node --test scripts/, Node ≥ 20 with the built-in test runner, no third-party deps). Coverage: semver comparison & tag/repo parsing (unit-semver.test.mjs), sync planning (unit-sync.test.mjs), tar extraction incl. path-escape safety (unit-tar.test.mjs), plus the host apply() smoke test.scripts/test-host-apply.mjs — isolation test that drives apply() with a fake context (also picked up by npm test).scripts/restart-service.ps1 — manual service restart helper (run with -ExecutionPolicy Bypass); pass -Launcher (or set DSH_RESTART_LAUNCHER) plus optional -Port/-WorkingDir/-Log.MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。