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
Hot-toggle any installed plugin from the DeepSeek Harness Web settings page (Plugins → 启停管理): stop or start a Cordis Loader entry in-process with instant effect and no DSH restart — the state persists across restarts.
中文文档 | English
The 启停管理 (Plugin Toggle) tab in the Web settings:

Entry.update({ disabled }) — disabling disposes the plugin fiber, enabling re-imports and starts it, all in-process with instant effect. No DSH restart needed.$DSH_HOME/profiles/<profile>/cordis.patch.yml) and hot-applied by the official HMR watcher on save — survives restarts.include, cordis:*, loader/hmr/timer, the dynamic-plugin host) cannot be toggled and are marked 「系统核心」.$DSH_HOME/plugins)pluginHotToggle, 39 balanced keys).dsh plugin --profile web add ./dsh-plugin-hot-toggle
dsh plugin --profile web add dsh-plugin-hot-toggle
dsh plugin --profile web add github:5102a/dsh-plugin-hot-toggle
After installation, start DSH (or let HMR apply it) and open Settings → Plugins → 启停管理.
The plugin runs on Windows, macOS, and Linux — the three platforms DeepSeek Harness itself supports.
| Concern | Guarantee |
|---|---|
| Host half | All filesystem paths go through node:path (join/dirname) and fileURLToPath; no hardcoded separators |
| Persistence | Patch-layer writes use readFileSync/writeFileSync(…, 'utf8') with paths derived from the Loader include |
| HTTP API | /plugin-hot-toggle/api/* is a URL route — platform-independent |
| Client half | Pure browser fetch + React; no process.platform/navigator.platform branches |
| Build | scripts/build.mjs resolves paths from import.meta.url via fileURLToPath + join |
| Dev tooling | Chrome/Edge discovery honors CHROME_PATH/CHROME_BIN or a cross-platform candidate list; DSH_URL overrides the target origin |
| CI | GitHub Actions matrix: ubuntu + windows + macos × Node 18/20/22 |
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ Web (client half) │ fetch │ Node (host half) │
│ settings.plugins.tab │ ──────► │ /plugin-hot-toggle/api/* │
│ 「启停管理」tab │ JSON │ ┌──────────────────────────┐ │
│ - list + filters + sort │ ◄────── │ │ ctx.loader.entries() │ │
│ - toggle buttons │ │ │ entry.update({disabled}) │ │
└─────────────────────────────┘ │ │ → fiber dispose / start │ │
│ └──────────────────────────┘ │
│ ┌──────────────────────────┐ │
│ │ persistence: write │ │
│ │ cordis.patch.yml → HMR │ │
│ └──────────────────────────┘ │
└──────────────────────────────┘
loader, webServer, dshHomePath) — zero DSH core changes. webServer is injected dynamically, so TUI/headless surfaces never pend.src/client.js by a zero-dependency build script (node scripts/build.mjs) and committed to the repo, so git/npm installs need no build step.dsh-plugin-hot-toggle/
├── package.json # dsh.bundle declaration + peerDependencies + exports
├── index.d.ts # Host half type declarations
├── index.js # Node half: loader list/toggle + webServer HTTP API
├── cordis.patch.yml # bundle layer: inserts the plugin row
├── src/client.js # Web half source (React)
├── lib/client.js # Web half build artifact (generated, do not edit)
├── scripts/build.mjs # zero-dep client bundle build
├── scripts/screenshot.mjs # headless-Chrome UI screenshot (CDP, zero deps)
├── scripts/verify-render.mjs # verify the 启停管理 tab rendered
├── scripts/debug-dom.mjs # DOM/slot debugging helper
├── tests/patch.test.js # unit tests (node:test)
├── docs/DSH-PLUGIN-DEVELOPMENT-SOP.md # end-to-end DSH plugin development SOP (bilingual)
├── .dsh/skills/dsh-plugin-hot-toggle/SKILL.md # project skill: dev/build/publish SOP
└── .github/workflows/ci.yml # CI: build + artifact freshness + tests
| Method | Path | Body | Returns |
|---|---|---|---|
| GET | /plugin-hot-toggle/api/list |
— | { entries: PluginEntry[] } |
| POST | /plugin-hot-toggle/api/setEnabled |
{ entryId, enabled } |
SetEnabledResponse |
See index.d.ts for PluginEntry / SetEnabledResponse.
npm run build # generate lib/client.js from src/client.js
npm test # node:test unit tests
npm run check # build + test in one step
Releases are fully automated via OIDC trusted publishing — pushing a version tag triggers the Release workflow, which builds, tests, packs, publishes to npm (with provenance), and creates a GitHub Release. No npm token or manual 2FA is needed.
npm version 0.1.5 --no-git-tag-version # bump version
git commit -am "chore: release v0.1.5"
git tag v0.1.5
git push origin master --tags # CI + Release workflow + npm publish (OIDC)
The name
dsh-plugin-hot-togglewas verified available withnpm viewbefore release.
Note on peer-dependency warnings: the package declares
@deepseek-ai/cordisandreactas peer dependencies (the same pattern as the official@deepseek-ai/*plugins). DSH resolves them from its own installation via the profile's flat fallback, so an "unmet peer" warning duringdsh plugin addis expected and harmless.
MIT — see LICENSE.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。