Installing dsh-freeweb

August 23, 2026 · View on GitHub

Requirements

  • Node.js ≥ 20.3 (the plugin is pure ESM with zero runtime dependencies, so this is the only toolchain requirement).
  • A working dsh installation (npx -y @deepseek-ai/dsh).
  • Verified against @deepseek-ai/dsh 0.1.1-rc.2; the plugin touches exactly three stable surfaces (see dsh.md).

All commands below install into the web profile — the one the browser UI uses. Substitute your own profile name if you boot a different one.

The shortest route is Path B — straight from GitHub. Path A covers source checkouts and offline machines.

Path A — local directory

  1. Get the code onto disk: clone the repository, unzip a release archive, or copy the folder across.

    git clone https://github.com/wiselfx/dsh-freeweb.git /opt/dsh-freeweb
    
  2. Add it to the profile by absolute path:

    npx -y @deepseek-ai/dsh plugin --profile web add /opt/dsh-freeweb
    
  3. Restart dsh (see Restart requirement).

  4. Verify (see Verify the install).

The path you pass must contain this package's package.json.

Path B — straight from GitHub

dsh plugin forwards install specs verbatim to pnpm, so a GitHub shorthand installs directly — no npm account, no local clone. Verified against dsh 0.1.1-rc.2 with the npm registry unreachable (resolution goes through GitHub's codeload tarballs):

npx -y @deepseek-ai/dsh plugin --profile web add wiselfx/dsh-freeweb

Variants that also work: full URLs (https://github.com/wiselfx/dsh-freeweb.git), pinned refs (wiselfx/dsh-freeweb#v0.1.0), and the explicit github: prefix. Updates re-run the same command; pin a tag first if you want reproducible installs.

Two notes: this package declares no build/lifecycle scripts, so pnpm 11's build gate never applies; and because the install is a real package install, the profile loads it from its own store — you do not need to keep any clone around (unlike Path A).

Path C — from npm (optional)

If the package is ever published, a plain spec installs it without GitHub:

npx -y @deepseek-ai/dsh plugin --profile web add dsh-freeweb

Updates become plugin add dsh-freeweb@<version>. Until a publish exists, use Path A or B.

What the install changes

The bundle contributes two patch operations to the profile tree:

  1. It sets the web seam's searchProvider config to freeweb.
  2. It inserts the package root as the freeweb plugin.

Nothing else moves. dsh's built-in web_search tool, citation cards, and UI are untouched; only the backend behind them changes. Any later profile patch can pin another provider back (see Switching providers).

Restart requirement

dsh composes its profile tree at startup: plugins are loaded, bundles applied, and plugin config resolved when the process boots. Adding, removing, reinstalling, or reconfiguring dsh-freeweb therefore requires restarting dsh before anything changes.

One deliberate exception: Firecrawl credentials are checked per search, not cached at startup. With engines.firecrawl: auto (the default), a key or self-hosted endpoint present in the environment is picked up on subsequent searches without touching the config again.

Verify the install

No model call, no quota spent — this only prints the composed profile tree:

npx -y @deepseek-ai/dsh --profile web --dump-config

Expect the web row to carry searchProvider: freeweb and an inserted freeweb row to exist:

- id: web
  config:
    searchProvider: freeweb

- insert:
    - id: freeweb
      name: 'dsh-freeweb'

(Your dump will show the full composed tree; the excerpt above shows the two rows to look for.)

Also useful:

npx -y @deepseek-ai/dsh plugin --profile web list --depth 0

For an end-to-end check without the harness:

node /path/to/dsh-freeweb/test/integration.mjs "your query here"

Switching providers

To route the web seam back to another provider (e.g. modsearch), pin the web row again in a later patch layer:

- id: web
  config:
    searchProvider: modsearch

A later patch replaces the targeted row's whole config, so include any other keys that row needs. For a one-off flip without editing the profile, pass an overlay file: npx -y @deepseek-ai/dsh --profile web --patch flip.yaml (--patch layers apply after the profile). Restart dsh afterwards, then confirm with --dump-config. The freeweb plugin can stay installed while unselected; it costs nothing unless chosen.

Uninstall

npx -y @deepseek-ai/dsh plugin --profile web remove dsh-freeweb

(The plugin command forwards arguments verbatim to pnpm inside the profile, so this removes the installed package regardless of which path you used to add it.) Then restart dsh and re-run --dump-config: the freeweb rows should be gone and the web row should show whichever provider the remaining layers pin. If it shows nothing usable, pin one explicitly as shown above.

If you installed from a local directory, removing the directory before uninstalling leaves the profile pointing at nothing — run the remove first.

Troubleshooting

SymptomMeaningFix
--dump-config still shows another provider after installdsh was not restarted, or a later patch layer overrides the web rowrestart dsh; check for a later searchProvider patch and remove or reorder it
New engine/deadline config has no effectsame reason — plugin config is read at bootrestart dsh
web seam has no registerSearchProvider in the logthe seam surface moved in a newer dshcheck the compatibility list in dsh.md; the plugin degrades instead of crashing
all keyless engines failedevery enabled engine was bot-walled or unreachable from this networkretry later; enable more engines; or use a keyed provider for that egress
Only perplexity appears in "engines answering"DDG/Startpage challenged your IP (common on datacenter hosts)expected sometimes; consensus still returns results plus the answer
Firecrawl never participatesno credential found (FIRECRAWL_API_KEY, explicit key, or non-default base URL)set one; auto mode picks it up per search — see Restart requirement
Firecrawl returns 403 "IP looks suspicious"the hosted keyless tier rejects datacenter/shared egress IPsuse the free API key or a self-hosted endpoint