{"_id":"@anht3889/dsh-web-search-bundle","_rev":"2-5ae0d2e11f05437ca71ad50ab05c424c","name":"@anht3889/dsh-web-search-bundle","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@anht3889/dsh-web-search-bundle","version":"0.1.0","keywords":["web-search","tavily","brave-search","searxng","deepseek","deepseek-harness","dsh","settings","cordis"],"license":"MIT","_id":"@anht3889/dsh-web-search-bundle@0.1.0","maintainers":[{"name":"anht3889","email":"anh.tran.3889@gmail.com"}],"homepage":"https://github.com/anht3889/dsh-web-search#readme","bugs":{"url":"https://github.com/anht3889/dsh-web-search/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-web-react"],"platform":"web"}},"dist":{"shasum":"d56e108d590a6d9e8ad1291a9dfb7d1cd6960442","tarball":"https://registry.npmjs.org/@anht3889/dsh-web-search-bundle/-/dsh-web-search-bundle-0.1.0.tgz","fileCount":37,"integrity":"sha512-XMvWRk4aGBcWvOZDeqq84duoQuDbaDebpR9LM72d1IvXUjiNTcSD7mJUFkwUofG4+lNsfgV60sv0yI/nAujOlw==","signatures":[{"sig":"MEUCIBDU3QiaHOwia31Kzdhw6rDifNkZi/muCpE++rXnHkeLAiEAlkVzK/4Pg9+RmeFXI03nqW142jAPWIqUaewknkqsp8Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131148},"main":"lib/index.js","type":"module","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./client":{"types":"./lib/types/client/index.d.ts","default":"./lib/client.js"},"./manager":{"types":"./lib/types/manager/index.d.ts","default":"./lib/manager/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"0b7888f83545e3ac0adcbbc8ef9b7d865107af92","scripts":{"build":"pnpm run clean && tsc -p tsconfig.manager.json && tsc -p tsconfig.json && tsdown","clean":"node scripts/clean.mjs","bundle":"tsdown","verify:package":"node tests/pack-smoke.mjs"},"_npmUser":{"name":"anht3889","email":"anh.tran.3889@gmail.com"},"repository":{"url":"git+https://github.com/anht3889/dsh-web-search.git","type":"git","directory":"packages/bundle"},"_npmVersion":"10.9.8","description":"DeepSeek Harness multi-engine web-search provider and Settings section","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@deepseek-ai/schemastery":"3.18.1","@deepseek-ai/dsh-home-paths":"0.1.0-rc.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"clsx":"^2.1.1","jsdom":"^28.1.0","react":"^18.3.1","tsdown":"^0.22.14","js-yaml":"^4.3.1","react-dom":"^18.3.1","@types/node":"^26.2.0","@types/react":"~18.3.31","lightningcss":"^1.32.0","@types/js-yaml":"^4.0.9","@types/react-dom":"~18.3.7","@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-web":"0.1.0-rc.6","@deepseek-ai/dsh-brand":"0.1.0-rc.6","@deepseek-ai/dsh-timeout":"0.1.0-rc.6","@deepseek-ai/dsh-attachment":"0.1.0-rc.6","@deepseek-ai/dsh-invariants":"0.1.0-rc.6","@deepseek-ai/dsh-client-locale":"link:../../../deepseek-harness/packages/client/locale","@deepseek-ai/dsh-client-runtime":"link:../../../deepseek-harness/packages/client/runtime","@deepseek-ai/dsh-client-ui-slots":"link:../../../deepseek-harness/packages/client/ui-slots","@deepseek-ai/cordis-plugin-loader":"1.0.2","@deepseek-ai/dsh-client-web-react":"link:../../../deepseek-harness/packages/client/web-react","@deepseek-ai/cordis-plugin-include":"1.0.6","@deepseek-ai/dsh-client-ui-settings":"link:../../../deepseek-harness/packages/client/ui-settings","@deepseek-ai/dsh-client-ui-primitives":"link:../../../deepseek-harness/packages/client/ui-primitives"},"peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0","@deepseek-ai/cordis":"*","@deepseek-ai/dsh-web":"*","@deepseek-ai/dsh-invariants":"*","@deepseek-ai/dsh-client-locale":"*","@deepseek-ai/dsh-client-runtime":"*","@deepseek-ai/dsh-client-ui-slots":"*","@deepseek-ai/dsh-client-web-react":"*","@deepseek-ai/dsh-client-ui-settings":"*","@deepseek-ai/dsh-client-ui-primitives":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-web-search-bundle_0.1.0_1787300507207_0.2741454349732928","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@anht3889/dsh-web-search-bundle","version":"0.2.0","description":"DeepSeek Harness multi-engine web-search provider and Settings section","keywords":["web-search","tavily","brave-search","searxng","deepseek","deepseek-harness","dsh","settings","cordis"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/anht3889/dsh-web-search.git","directory":"packages/bundle"},"license":"MIT","type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./manager":{"types":"./lib/types/manager/index.d.ts","default":"./lib/manager/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./client":{"types":"./lib/types/client/index.d.ts","default":"./lib/client.js"},"./cordis.patch.yml":"./cordis.patch.yml","./package.json":"./package.json"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"platform":"web","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-web-react"]}},"scripts":{"clean":"node scripts/clean.mjs","build":"pnpm run clean && tsc -p tsconfig.manager.json && tsc -p tsconfig.json && tsdown","bundle":"tsdown","verify:package":"node tests/pack-smoke.mjs"},"dependencies":{"@anht3889/dsh-web-search-service":"0.1.0","@deepseek-ai/dsh-home-paths":"0.1.0-rc.6","@deepseek-ai/schemastery":"3.18.1"},"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-client-locale":"*","@deepseek-ai/dsh-client-runtime":"*","@deepseek-ai/dsh-client-ui-primitives":"*","@deepseek-ai/dsh-client-ui-settings":"*","@deepseek-ai/dsh-client-ui-slots":"*","@deepseek-ai/dsh-client-web-react":"*","@deepseek-ai/dsh-invariants":"*","@deepseek-ai/dsh-web":"*","react":"^18.2.0","react-dom":"^18.2.0"},"devDependencies":{"@deepseek-ai/cordis":"4.0.1","@deepseek-ai/cordis-plugin-include":"1.0.6","@deepseek-ai/cordis-plugin-loader":"1.0.2","@deepseek-ai/dsh-attachment":"0.1.0-rc.6","@deepseek-ai/dsh-brand":"0.1.0-rc.6","@deepseek-ai/dsh-client-locale":"link:../../../deepseek-harness/packages/client/locale","@deepseek-ai/dsh-client-runtime":"link:../../../deepseek-harness/packages/client/runtime","@deepseek-ai/dsh-client-ui-primitives":"link:../../../deepseek-harness/packages/client/ui-primitives","@deepseek-ai/dsh-client-ui-settings":"link:../../../deepseek-harness/packages/client/ui-settings","@deepseek-ai/dsh-client-ui-slots":"link:../../../deepseek-harness/packages/client/ui-slots","@deepseek-ai/dsh-client-web-react":"link:../../../deepseek-harness/packages/client/web-react","@deepseek-ai/dsh-invariants":"0.1.0-rc.6","@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-timeout":"0.1.0-rc.6","@deepseek-ai/dsh-web":"0.1.0-rc.6","@types/js-yaml":"^4.0.9","@types/node":"^26.2.0","@types/react":"~18.3.31","@types/react-dom":"~18.3.7","clsx":"^2.1.1","js-yaml":"^4.3.1","jsdom":"^28.1.0","lightningcss":"^1.32.0","react":"^18.3.1","react-dom":"^18.3.1","tsdown":"^0.22.14"},"_id":"@anht3889/dsh-web-search-bundle@0.2.0","gitHead":"94b3f56bee392fd59d408ffafd617b63349ef9b8","bugs":{"url":"https://github.com/anht3889/dsh-web-search/issues"},"homepage":"https://github.com/anht3889/dsh-web-search#readme","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-m8vTdqYuG7otic3x1BZHG8IIun9p9KqYXWhhu7g/7sF7DlSUP47WvYiufaPfJ/HvmnXrbDnLiO84tddgesA9Gg==","shasum":"c053e6ffa6c85b0cee50aef8de5915fb28aea1e1","tarball":"https://registry.npmjs.org/@anht3889/dsh-web-search-bundle/-/dsh-web-search-bundle-0.2.0.tgz","fileCount":37,"unpackedSize":130827,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCcYGu6u/YSPMkj2t54lIPG4bpqrHxdsxXKJr3Mo0YacgIhAIUFe9IQmiqE5W1G9L0yrheAWgL/ywBQhLgvM0I7sZAG"}]},"_npmUser":{"name":"anht3889","email":"anh.tran.3889@gmail.com"},"directories":{},"maintainers":[{"name":"anht3889","email":"anh.tran.3889@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-web-search-bundle_0.2.0_1787542646525_0.3723803449171541"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-21T08:21:47.011Z","modified":"2026-08-24T03:37:26.817Z","0.1.0":"2026-08-21T08:21:47.341Z","0.2.0":"2026-08-24T03:37:26.685Z"},"bugs":{"url":"https://github.com/anht3889/dsh-web-search/issues"},"license":"MIT","homepage":"https://github.com/anht3889/dsh-web-search#readme","keywords":["web-search","tavily","brave-search","searxng","deepseek","deepseek-harness","dsh","settings","cordis"],"repository":{"type":"git","url":"git+https://github.com/anht3889/dsh-web-search.git","directory":"packages/bundle"},"description":"DeepSeek Harness multi-engine web-search provider and Settings section","maintainers":[{"name":"anht3889","email":"anh.tran.3889@gmail.com"}],"readme":"# @anht3889/dsh-web-search-bundle\n\nInstallable DeepSeek Harness Web-profile bundle that registers the `dsh-web-search` provider and its Settings section for Tavily, Brave Search, and SearXNG.\n\n## Prerequisites\n\n- The `dsh` CLI and a Web profile.\n- For a source checkout: Node.js `^22.19` or `>=24`, pnpm, and a sibling `../deepseek-harness` checkout. Client typecheck and `tsdown` extend that tree; published installs use the prebuilt package and do not need it.\n- A Tavily or Brave API key for that engine, or a private SearXNG instance you operate or trust.\n\n## Install\n\nAdd the published package to a profile. `@anht3889/dsh-web-search-service` is a nested dependency of this bundle, not a second plugin.\n\n```sh\ndsh plugin --profile web add @anht3889/dsh-web-search-bundle\n```\n\nFrom the repository root of a local source checkout, build and add the workspace path instead of the npm name:\n\n```sh\npnpm install && pnpm run build\ndsh plugin --profile web add ./packages/bundle\n```\n\nRestart the Web profile after either install:\n\n```sh\ndsh --profile web\n```\n\nOpen **Settings → 网络搜索** (**Web search** in the English locale), select an engine, enter its required key or URL, and save. Engine changes apply to the next search without another restart.\n\n## Engines\n\n| Engine | Default base URL | Required configuration |\n|---|---|---|\n| Tavily | `https://api.tavily.com` | `TAVILY_API_KEY` |\n| Brave Search | `https://api.search.brave.com` | `BRAVE_API_KEY` |\n| SearXNG | None | Private instance base URL |\n\nThe initial engine is unselected, so the pinned provider is unavailable until an engine is configured. SearXNG has no public default: use a private instance you operate or trust, and enable JSON responses in its settings. Searches request `format=json`; a 403 response usually means the instance does not allow `format: json`.\n\n## Configuration and secrets\n\n| Data | Default location |\n|---|---|\n| Engine selection and base URLs; no secret values | `$DSH_HOME/web-search/config.json` |\n| Fallback key storage | `$DSH_HOME/web-search/secrets.yaml` |\n| Key references | `TAVILY_API_KEY`, `BRAVE_API_KEY` |\n\nSecret resolution uses the first non-empty value from the mounted `ctx.credentials` service, the private fallback file, then the process environment. Settings writes keys through `ctx.credentials` when it is mounted; otherwise it writes the fallback file. The HTTP API and Settings status expose only whether each key is configured, never its value.\n\nIf no Host webserver is mounted, the provider still supports headless searches, but the Settings UI and management HTTP routes are unavailable. Configure the same catalog and secret locations before starting that composition.\n\n## Runtime and HTTP\n\nThe bundle pins `web.searchProvider` to `dsh-web-search`. DeepSeek's `deepseek-official` provider remains installed but is unused while that pin is active; an unavailable wrapper does not silently fall back to it.\n\nThe manager publishes `ctx.webSearchManager` from `@anht3889/dsh-web-search-service`. Hosts without a loopback HTTP API use that service to manage the same runtime directly.\n\n- `GET` and `PUT /web-search/config` read or replace the non-secret catalog.\n- `GET /web-search/secrets` reports configured flags only.\n- `PUT /web-search/secrets` accepts write-only key updates; omitted or empty values leave existing keys unchanged.\n\n## Restore DeepSeek search\n\nPut this exact layer in the Web profile patch at `$DSH_HOME/profiles/web/cordis.patch.yml`:\n\n```yaml\n- id: web\n  config:\n    searchProvider: deepseek-official\n```\n\nRestart the Web profile. A patch row replaces the complete `web` config, so add any other required `web` config keys to the same mapping.\n\n## Exports\n\n| Export | Purpose |\n|---|---|\n| `@anht3889/dsh-web-search-bundle` | Host loader entry for the browser Settings plugin |\n| `@anht3889/dsh-web-search-bundle/manager` | Provider manager and runtime API |\n| `@anht3889/dsh-web-search-bundle/client` | Browser Settings plugin bundle |\n| `@anht3889/dsh-web-search-bundle/invariant` | Package-owned invariant plugin |\n| `@anht3889/dsh-web-search-bundle/cordis.patch.yml` | Installable profile patch |\n| `@anht3889/dsh-web-search-bundle/package.json` | Package manifest |\n\n## Troubleshooting\n\n- **`WEB_PROVIDER_CONFIGURED_UNAVAILABLE`:** Select an engine. For SearXNG, also provide a valid absolute private-instance URL. There is no automatic DeepSeek fallback.\n- **Missing Tavily or Brave key:** Set the matching key in Settings, `ctx.credentials`, the fallback secrets file, or the process environment. The provider can appear available before key resolution, but the search call fails with `WEB_PROVIDER_ERROR` when the key is absent.\n- **SearXNG HTTP 403:** Enable JSON output (`format: json`) in the instance settings and confirm you are using your private instance.\n- **Corrupt `config.json`:** Host startup fails if `$DSH_HOME/web-search/config.json` exists but is not valid JSON or fails catalog validation (unknown keys, invalid engine, or SearXNG selected without an absolute URL). Delete the file to restore the empty catalog, or fix the JSON. Do not put secrets in this file.\n","readmeFilename":"README.md"}