{"_id":"@djdowbnac/dsh-web-search-local","_rev":"4-ad55cfe3ee1145837316f934767bf211","name":"@djdowbnac/dsh-web-search-local","dist-tags":{"latest":"1.1.4"},"versions":{"1.1.0":{"name":"@djdowbnac/dsh-web-search-local","version":"1.1.0","license":"MIT","_id":"@djdowbnac/dsh-web-search-local@1.1.0","maintainers":[{"name":"trimedeo","email":"demetriodowbnac@gmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-slots","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"platform":"web"}},"dist":{"shasum":"9489f5d8a7b72ca04bcfc0f5bb9ed4c79e6b3384","tarball":"https://registry.npmjs.org/@djdowbnac/dsh-web-search-local/-/dsh-web-search-local-1.1.0.tgz","fileCount":7,"integrity":"sha512-P9riE0hzfgo1MBoQlHIwg6DkzTFc8GBYcnveq3coOVCK1u0TflejBWaB+wL+4kpL5Y4RWDQd/iAWVQioJAurCA==","signatures":[{"sig":"MEYCIQCqR5Pd+Fb77jWp5ozlAje8QYOqACJw4puMxvWR357nFQIhANiH1a2NYKPysKPcVffq4CS5nF4JVW/9axdhibc6Mmqy","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":238594},"main":"lib/index.js","type":"module","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./src/*":"./src/*","./client":{"types":"./lib/types/client/index.d.ts","default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"2fd4407cc3b4ca855397572df139eab83b02a47a","scripts":{"test":"bun test","build":"bun build src/index.ts --target node --format esm --outdir lib && node scripts/strip-bundle-comments.mjs lib/index.js --write"},"_npmUser":{"name":"trimedeo","email":"demetriodowbnac@gmail.com"},"_npmVersion":"11.11.0","description":"Web-search provider for the DeepSeek Harness (ctx.web): real internet search via a built-in in-process metasearch or DuckDuckGo only, no external API key, no external instance, zero runtime dependencies, plus an optional fully-local corpus full-text index","directories":{},"_nodeVersion":"24.14.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.4.2","typescript":"~7.0.0","semantic-release":"25.0.9","@deepseek-ai/dsh-web":"^0.1.2-rc.1","@semantic-release/git":"11.0.1","@semantic-release/npm":"13.1.5","@deepseek-ai/schemastery":"^3.18.2","@semantic-release/changelog":"7.0.0","@semantic-release/commit-analyzer":"13.0.1","@semantic-release/release-notes-generator":"14.1.1"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.2","@deepseek-ai/dsh-web":"^0.1.2-rc.1","@deepseek-ai/dsh-agent":"^0.1.2-rc.1","@deepseek-ai/dsh-session":"^0.1.2-rc.1","@deepseek-ai/dsh-settings":"^0.1.2-rc.1","@deepseek-ai/dsh-credentials":"^0.1.2-rc.1","@deepseek-ai/dsh-launch-environment":"^0.1.2-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-web-search-local_1.1.0_1789010792295_0.02874141845650624","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@djdowbnac/dsh-web-search-local","version":"1.1.2","license":"MIT","_id":"@djdowbnac/dsh-web-search-local@1.1.2","maintainers":[{"name":"trimedeo","email":"demetriodowbnac@gmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-slots","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"platform":"web"}},"dist":{"shasum":"87aff091e9e3af8250542214c1ed96bb6ce1be23","tarball":"https://registry.npmjs.org/@djdowbnac/dsh-web-search-local/-/dsh-web-search-local-1.1.2.tgz","fileCount":7,"integrity":"sha512-vi6arVGrhMwOkLHNWco5k46SSGObmRK6mF3kEJELqA1X3PvUN7xpGCYRjEOCOTe9jUMpeAwnRrWNdORnWUNEvw==","signatures":[{"sig":"MEUCIQC02lX4AjI/W0aQDdcsKbC5bXg/68Z9I/54af5wzWDGiwIgc0/jgvd105THE2vkXrThAjCdTMUqhOmDqklqBYBwLJA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICWszV/qY8dAL7qNXpaVahzxZ88PEiHIrjy0btijcvBwAiAX95HDBT3fIDHXqawXVCqXguD/e53LHD42+jj2KMlW2g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":238523},"main":"lib/index.js","type":"module","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./src/*":"./src/*","./client":{"types":"./lib/types/client/index.d.ts","default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"079346b8f868a017143732058ee31851444ec3e4","scripts":{"test":"bun test","build":"bun build src/index.ts --target node --format esm --outdir lib && node scripts/strip-bundle-comments.mjs lib/index.js --write"},"_npmUser":{"name":"trimedeo","email":"demetriodowbnac@gmail.com"},"_npmVersion":"10.9.8","description":"Web-search provider for the DeepSeek Harness (ctx.web): real internet search via a built-in in-process metasearch or DuckDuckGo only, no external API key, no external instance, zero runtime dependencies, plus an optional fully-local corpus full-text index","directories":{},"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.4.2","typescript":"~7.0.0","semantic-release":"25.0.9","@deepseek-ai/dsh-web":"^0.1.2-rc.1","@semantic-release/git":"11.0.1","@semantic-release/npm":"13.1.5","@deepseek-ai/schemastery":"^3.18.2","@semantic-release/changelog":"7.0.0","@semantic-release/commit-analyzer":"13.0.1","@semantic-release/release-notes-generator":"14.1.1"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.2","@deepseek-ai/dsh-web":"^0.1.2-rc.1","@deepseek-ai/dsh-agent":"^0.1.2-rc.1","@deepseek-ai/dsh-session":"^0.1.2-rc.1","@deepseek-ai/dsh-settings":"^0.1.2-rc.1","@deepseek-ai/dsh-credentials":"^0.1.2-rc.1","@deepseek-ai/dsh-launch-environment":"^0.1.2-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-web-search-local_1.1.2_1789012315858_0.10510846651614303","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"@djdowbnac/dsh-web-search-local","version":"1.1.3","license":"MIT","_id":"@djdowbnac/dsh-web-search-local@1.1.3","maintainers":[{"name":"trimedeo","email":"demetriodowbnac@gmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-slots","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"platform":"web"}},"dist":{"shasum":"ee54cc256b4ece28e5701bff367559f124d7cfcd","tarball":"https://registry.npmjs.org/@djdowbnac/dsh-web-search-local/-/dsh-web-search-local-1.1.3.tgz","fileCount":7,"integrity":"sha512-Jn7aQDOKK7SQIlK3ua0qa53lcwrAmitjtdfCfaEwS7Lkyf08/AZaNoNn1jw71lESC+Nl7+OwQOdW74MAMwmN7Q==","signatures":[{"sig":"MEQCIHdD9LUR1Xo6ol8pnmwVqQC2MI+uFcaugnTdtkw3RmsmAiAQa9KG/YSoSMDvbJiboV5kRZZcUTtqa3xAaiYWo65dFg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIEBncijrjfNvUTVaEVbjglRtWWhPRQ94YnPFOg4CaDJZAiB6YAwS54TBseEvu8snM28lIf5gdlaJTulqAmrY64zn9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":218475},"main":"lib/index.js","type":"module","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./src/*":"./src/*","./client":{"types":"./lib/types/client/index.d.ts","default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"5af17d6d498b76e1a92f940665f2e6a5d18b78ba","scripts":{"test":"bun test","build":"bun build src/index.ts --target node --format esm --outdir lib && node scripts/strip-bundle-comments.mjs lib/index.js --write"},"_npmUser":{"name":"trimedeo","email":"demetriodowbnac@gmail.com"},"_npmVersion":"10.9.8","description":"Web-search provider for the DeepSeek Harness (ctx.web): real internet search via a built-in in-process metasearch or DuckDuckGo only, no external API key, no external instance, zero runtime dependencies, plus an optional fully-local corpus full-text index","directories":{},"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.4.2","typescript":"~7.0.2","semantic-release":"25.0.9","@deepseek-ai/dsh-web":"^0.1.2-rc.1","@semantic-release/git":"11.0.1","@semantic-release/npm":"13.1.5","@deepseek-ai/schemastery":"^3.18.2","@semantic-release/changelog":"7.0.0","@semantic-release/commit-analyzer":"13.0.1","@semantic-release/release-notes-generator":"14.1.1"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.2","@deepseek-ai/dsh-web":"^0.1.2-rc.1","@deepseek-ai/dsh-agent":"^0.1.2-rc.1","@deepseek-ai/dsh-session":"^0.1.2-rc.1","@deepseek-ai/dsh-settings":"^0.1.2-rc.1","@deepseek-ai/dsh-credentials":"^0.1.2-rc.1","@deepseek-ai/dsh-launch-environment":"^0.1.2-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-web-search-local_1.1.3_1789238780682_0.9519678128293168","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"_id":"@djdowbnac/dsh-web-search-local@1.1.4","dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-slots","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"platform":"web"}},"dist":{"shasum":"7f732c78cc2ee352c5a318e7f9c367d04981dc32","tarball":"https://registry.npmjs.org/@djdowbnac/dsh-web-search-local/-/dsh-web-search-local-1.1.4.tgz","fileCount":7,"integrity":"sha512-QFZXdKJSIQG0fpIuk+26mle95xxm3FPBsgPhyyh/g0zTvRvjQbzSo1cmG0nTfeWiFYE/vDYkKcfHCwDvapGyxA==","signatures":[{"sig":"MEUCIGNuH+jLAPHbspcRaP1xZc4n54hHxy8OqWY9tuxzS7IiAiEA/bPnW3YPOEZlP+0DWYiijlHgOTbEMFrFAZBDe4NqHyw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFeMe8Fjrl1mgKqM00C4FGkHMsltB3faM+hBVGoJih+vAiEA7GJlyzMMvcnMGK+VvbV9HxolybgIpHxZWaLuRI/eNSE="}],"unpackedSize":230381},"main":"lib/index.js","name":"@djdowbnac/dsh-web-search-local","type":"module","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./src/*":"./src/*","./client":{"types":"./lib/types/client/index.d.ts","default":"./lib/client.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"48acbcdd9b7ea1ac58d5ef47bda6cb68e65719af","license":"MIT","scripts":{"test":"bun test","build":"bun build src/index.ts --target node --format esm --outdir lib && node scripts/strip-bundle-comments.mjs lib/index.js --write"},"version":"1.1.4","_npmUser":{"name":"trimedeo","email":"demetriodowbnac@gmail.com"},"_npmVersion":"10.9.8","description":"Web-search provider for the DeepSeek Harness (ctx.web): real internet search via a built-in in-process metasearch or DuckDuckGo only, no external API key, no external instance, zero runtime dependencies, plus an optional fully-local corpus full-text index","directories":{},"maintainers":[{"name":"trimedeo","email":"demetriodowbnac@gmail.com"}],"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.4.2","typescript":"~7.0.2","semantic-release":"25.0.9","@deepseek-ai/dsh-web":"^0.1.7-rc.2","@semantic-release/git":"11.0.1","@semantic-release/npm":"13.1.5","@deepseek-ai/schemastery":"^3.18.3","@semantic-release/changelog":"7.0.0","@semantic-release/commit-analyzer":"13.0.1","@semantic-release/release-notes-generator":"14.1.1"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.2","@deepseek-ai/dsh-web":"^0.1.7-rc.2","@deepseek-ai/dsh-agent":"^0.1.7-rc.2","@deepseek-ai/dsh-session":"^0.1.7-rc.2","@deepseek-ai/dsh-settings":"^0.1.7-rc.2","@deepseek-ai/dsh-credentials":"^0.1.7-rc.2","@deepseek-ai/dsh-launch-environment":"^0.1.7-rc.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-web-search-local_1.1.4_1790643339581_0.985755841865247"}}},"time":{"created":"2026-09-10T03:26:32.087Z","modified":"2026-09-29T00:55:39.894Z","1.1.0":"2026-09-10T03:26:32.450Z","1.1.2":"2026-09-10T03:51:55.937Z","1.1.3":"2026-09-12T18:46:20.763Z","1.1.4":"2026-09-29T00:55:39.683Z"},"license":"MIT","description":"Web-search provider for the DeepSeek Harness (ctx.web): real internet search via a built-in in-process metasearch or DuckDuckGo only, no external API key, no external instance, zero runtime dependencies, plus an optional fully-local corpus full-text index","maintainers":[{"name":"trimedeo","email":"demetriodowbnac@gmail.com"}],"readme":"# @djdowbnac/dsh-web-search-local\n\nA web-search provider for the DeepSeek Harness without an account or API key, plus an optional fully local full-text index over your own files.\n\nThe plugin registers two search providers and one fetch provider on the `ctx.web` seam:\n\n| Provider | What it does | Network |\n|---|---|---|\n| `web` | Internet search via the built-in metasearch (`auto`, `searxng`) or DuckDuckGo only (`duckduckgo`). | outbound HTTPS to the upstreams |\n| `local` | Full-text search over a local corpus (BM25, snippets, incremental re-index, `bun:sqlite` FTS5 on Bun, pure-JS JSON on Node). | none |\n| `local` (fetch) | Reads `file://` URLs from disk and retrieves the `http(s)://` URLs `web_search` returns. | on fetch only |\n\nPin `web` when you want internet search without a keyed external API. The stock `web-search-deepseek` plugin requires a DeepSeek account and API key.\n\n## Internet search (`web`)\n\nThe `engine` field selects the backend (UI or YAML):\n\n- `auto` (default): the built-in metasearch. Fans out to DuckDuckGo, Bing, and Wikipedia in parallel, then merges, dedups, and ranks the hits. No instance, no URL, no setup.\n- `duckduckgo`: DuckDuckGo only, the keyless public endpoint `html.duckduckgo.com/html/`. Filters out the ad rows (`duckduckgo.com/y.js`).\n- `searxng`: the same built-in metasearch. The value name is kept for compatibility with the 0.1.x instance model.\n\n## Install and mount\n\nThe package is published on npm, so a normal install pulls the registry version:\n\n```bash\ndsh plugin --profile web add @djdowbnac/dsh-web-search-local\n```\n\nThat is the whole install. `dsh plugin` initializes the profile on first use and forwards to `pnpm add` inside the profile directory (pnpm must be on PATH). To pin an exact version, add the full specifier (`dsh plugin --profile web add @djdowbnac/dsh-web-search-local@1.1.2`).\n\nRemove it with:\n\n```bash\ndsh plugin --profile web remove @djdowbnac/dsh-web-search-local\n```\n\n### From a checkout (development)\n\nTo work on the plugin itself, point the same command at the checkout instead of the package name:\n\n```bash\n# from the plugin's checkout directory\ndsh plugin --profile web add .\n```\n\nThe directory becomes a pnpm local dependency, so the profile resolves the package name to this checkout, and the bundle registration works the same way. The dependency is a local link, so the profile always loads the current checkout. After editing sources, re-run `bun run build` for the change to take effect.\n\n### Zero-install (advanced)\n\nTo skip the pnpm dependency entirely, point the row's `name` at a built entry point. From a checkout, that is `bun run build` first, then:\n\n```yaml\nname: 'file:///<path>/dhs-web-search-local/lib/index.js'\n```\n\n### Mounting the integration\n\nThe dependency installs (npm or checkout) need no manual mount. The layer order is: the stock base/surface bundle layers, the package bundle layers in `dsh.profile.bundles` order (this plugin's is last among them), the profile's `cordis.patch.yml` (user layer), `$DSH_HOME/cordis.patch.yml`, and any `--patch` overlays: the later layer wins. So the shipped patch is a stock base the user layer overrides freely: set `corpusDirs`, switch `engine`, pin a different provider. Inspect the composed tree any time:\n\n```bash\ndsh --profile web --dump-config\n```\n\nFor the zero-install path (manual mount), apply `./cordis.patch.yml` as a `--patch` overlay, or merge its rows into the profile's `cordis.patch.yml` at `$DSH_HOME/profiles/web/cordis.patch.yml` (default home `~/.dsh`), adapting `name` to the `file://` entry. A patch replaces the target row's whole `config`, so the snippet restates `searchProvider` and `fetchProvider`:\n\n```yaml\n- insert:\n    - id: web-search-local\n      name: 'file:///<path>/dhs-web-search-local/lib/index.js'   # zero-install entry\n      config:\n        corpusDirs: [!!js process.cwd()]   # optional. Only used by the `local` provider\n        # engine: auto                     # auto | duckduckgo | searxng\n- id: web\n  config:\n    searchProvider: web      # <- internet. Use `local` for on-disk corpus search.\n    fetchProvider: local\n```\n\n> **Pinning is mandatory.** The stock `deepseek-official` provider is always \"available\", so without pinning `searchProvider` the seam reports `WEB_PROVIDER_AMBIGUOUS`. The stock `web-search-deepseek` / `web-fetch-http` rows may stay (registered but unselected). The shipped bundle patch does the pinning and deliberately sets no `corpusDirs`: an auto-applied layer must not index the boot directory. Set it in the user layer or via the settings section.\n\n## Configuration\n\nThe provider exposes the `web-search-local` settings section, persisted to `$DSH_HOME/settings.yaml` (hot-reloaded, so a change reaches the next search with no restart):\n\n| Field | Default | Meaning |\n|---|---|---|\n| `engine` | `auto` | Web backend: `auto` (metasearch: DuckDuckGo + Bing + Wikipedia), `duckduckgo`, or `searxng` (= metasearch, kept for 0.1.x compatibility). |\n| `corpusDirs` | `[]` | Directories to index (absolute or `~`). Only used by the `local` search provider. Empty returns an informed empty result. |\n| `include` | built-in text/code set | Extra extensions to index (with or without a leading dot). |\n| `exclude` | built-in (`node_modules`, `.git`, `*.min.js`, lockfiles, more) | Extra dir names, file names, or dot-suffixes to skip. |\n| `indexDir` | `<DSH home>/web-search-local` | Where `index.db` or `index.fallback.json` and `manifest.json` live. |\n| `maxResults` | `20` | Per-query source cap (the seam re-enforces the tool's bound). |\n| `snippetLength` | `160` | Approximate snippet length. |\n| `autoReindex` | `true` | Re-scan the corpus on each search (bounded by an internal interval). `false` = build on change only. |\n| `maxFileSizeBytes` | `5000000` | Skip files larger than this. |\n\nTwo ways to configure:\n\n1. **YAML (primary):** edit the `web-search-local` section in `$DSH_HOME/settings.yaml` (the same file the Settings UI writes). Example:\n   ```yaml\n   web-search-local:\n     engine: auto\n     corpusDirs:\n       - D:\\docs\n       - ~/notes\n   ```\n2. **UI card:** when the deployment renders third-party plugin cards, a card appears under Settings -> Plugins for `web-search-local` (engine, corpus dirs, max results, snippet length, index dir, auto-reindex, then Save). It is optional: when the deployment does not render cards, the YAML path remains fully functional.\n\n## Known limitations\n\n- Web coverage: DuckDuckGo, Bing, and Wikipedia, all keyless. Google is not scraped directly because its CAPTCHAs are fragile. Rate limits and anti-bot walls depend on IP reputation (datacenter vs. residential). A walled upstream just drops out, and the healthy upstreams' merged results are still served. The search throws `WEB_PROVIDER_ERROR` (with per-upstream detail) only when every non-optional upstream fails.\n- DDG anomaly pages: under heavy abuse, DuckDuckGo can serve a challenge or anomaly page instead of results. The adapter records it as a typed `challenge` failure, the same as any other upstream failure.\n- `publishedAt`: Wikipedia hits carry it (the API `timestamp`). DuckDuckGo and Bing hits do not, because those upstreams expose no reliable date. Local corpus results use the file mtime.\n","readmeFilename":"README.md"}