deepseek-web-retrieval 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/README.md +167 -45
  3. package/dist/cli.js +2303 -1836
  4. package/docs/adr/0002-shared-config-base-layer.md +43 -0
  5. package/docs/agents/codex.md +60 -32
  6. package/docs/agents/opencode-v2.md +69 -39
  7. package/docs/agents/pi.md +60 -31
  8. package/docs/design/config-layering-design.md +180 -0
  9. package/docs/design/installer-design.md +33 -20
  10. package/docs/integration.md +41 -7
  11. package/docs/research/control-matrix.md +17 -4
  12. package/docs/research/mcp-compatibility.md +9 -2
  13. package/docs/research/ori-question-sourcing.md +336 -0
  14. package/docs/research/result-quality-passthrough.md +159 -0
  15. package/docs/research/search-api-defaults.md +18 -2
  16. package/docs/research/search-inline-content.md +244 -0
  17. package/examples/opencode.global.jsonc +3 -2
  18. package/package.json +2 -1
  19. package/src/core/auth.ts +3 -0
  20. package/src/core/client.ts +26 -4
  21. package/src/core/config-file.ts +168 -0
  22. package/src/core/config-summary.ts +82 -0
  23. package/src/core/constants.ts +15 -1
  24. package/src/core/descriptions.ts +6 -2
  25. package/src/core/env.ts +99 -32
  26. package/src/core/format.ts +19 -1
  27. package/src/core/options.ts +22 -2
  28. package/src/core/search.ts +6 -0
  29. package/src/core/types.ts +11 -0
  30. package/src/installer/apply.ts +5 -3
  31. package/src/installer/cli.ts +92 -25
  32. package/src/installer/config-command.ts +116 -0
  33. package/src/installer/hosts/codex.ts +5 -3
  34. package/src/installer/hosts/opencode.ts +9 -5
  35. package/src/installer/hosts/pi.ts +10 -6
  36. package/src/installer/ownership.ts +54 -1
  37. package/src/installer/paths.ts +7 -1
  38. package/src/installer/state.ts +73 -19
  39. package/src/installer/types.ts +12 -0
  40. package/src/mcp/auth.ts +2 -3
  41. package/src/mcp/cli.ts +9 -51
  42. package/src/mcp/serve.ts +60 -0
  43. package/src/mcp/server.ts +7 -2
  44. package/src/opencode/plugin.ts +22 -2
  45. package/src/pi/extension.ts +78 -9
  46. package/src/version.ts +12 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,26 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project are documented here, with one sentence per item.
3
+ All notable changes to this project are documented here, one sentence per item.
4
+
5
+ ## 0.7.0
6
+
7
+ - Layer a shared config file (`$XDG_CONFIG_HOME/deepseek-web-retrieval/config.json`, camelCase keys) under the environment on every host, with the precedence `built-in defaults < shared file < DEEPSEEK_* environment < host-native config`; unknown and host-integration keys are warned about and ignored, and the API key stays out of the file.
8
+ - Add a `config` command that prints every knob with its effective value and source (default, file, or environment — a count-derived `maxResults` is labeled `count`), replays shared-file problems, and verifies the key, config, and network end to end with `config --search "<query>"`.
9
+ - Forward every `DEEPSEEK_*` option variable — not just the API key — in the Codex installer's `env_vars` entry, so shell-set knobs reach the stdio server without hand-editing `config.toml`.
10
+ - Surface DeepSeek's `rerank_score`, `authority`, and `site_name` on search results in both text and structured output, accept an optional `original_question` on the MCP and Pi search tools (sent as `ori_question`), and add the `searchLocalization` deployment knob.
11
+ - Couple `maxResults` to `count` when left unset — configuring only `count` was a silent no-op — and retry transient failures (408/425/429/5xx) twice by default instead of failing the billed call on the first attempt.
12
+ - Resolve the shared config directory the Windows way on win32 (`%APPDATA%`, with an explicitly set `XDG_CONFIG_HOME` still winning), for the shared config file and the installer's global records alike.
13
+ - Add `init --pin` to register the exact running CLI version (`deepseek-web-retrieval@<version>`) instead of the unpinned name, with package-identity comparisons that still match a pinned ref to its lineage.
14
+ - `config` now warns and exits 1 when a `DEEPSEEK_*` variable is set but unusable (unknown name, non-numeric value, no-op switch value) instead of silently showing the default.
15
+
16
+ ## 0.6.0
17
+
18
+ - Return distinct CLI exit codes — 2 for invalid command lines and 3 when a failed apply could not roll back — and document the codes in the usage text.
19
+ - Add a `version` subcommand, record the installer version in install records, and show it in `list` output.
20
+ - Route any command-line argument to the installer before the MCP server loads, so installer commands never depend on the server's dependency graph and a mistyped command no longer starts a server.
21
+ - Reject duplicate flags instead of silently keeping the last value, and print usage to stderr on a bare invocation.
22
+ - Wait up to five minutes for npm's post-upload processing before finalizing automated releases, with retry guidance if processing takes longer.
23
+ - Clarify OpenCode and Pi native integration and Codex MCP support across setup, upgrade, security, release, and issue-reporting documentation.
4
24
 
5
25
  ## 0.5.1
6
26
 
package/README.md CHANGED
@@ -1,50 +1,104 @@
1
1
  # DeepSeek Web Retrieval
2
2
 
3
- **Bringing [DeepSeek's in-house Search and Fetch APIs](https://api-docs.deepseek.com/guides/search) to coding agents.**
3
+ **DeepSeek Search and Fetch for OpenCode, Pi, and Codex.**
4
4
 
5
- An adapter layer for coding agents. The core is agent-agnostic; each adapter exposes the
6
- same retrieval behavior to a specific agent. OpenCode v2 has a native plugin adapter, Pi a
7
- native extension adapter, and an MCP server covers every other MCP-capable host. Guides for
8
- other coding agents are in progress.
5
+ Search the web and fetch pages as Markdown through
6
+ [DeepSeek's APIs](https://api-docs.deepseek.com/guides/search), using a **native OpenCode
7
+ plugin**, a **native Pi extension**, or **MCP for Codex**. All three share the same retrieval
8
+ core, with results formatted for each host.
9
9
 
10
- This is an unofficial community project. It is not affiliated with OpenCode or DeepSeek.
10
+ This is an unofficial community project, not affiliated with DeepSeek or the supported
11
+ host projects.
11
12
 
12
13
  ## Features
13
14
 
14
- - **One core, every host** — a native OpenCode v2 plugin, a native Pi extension, plus a
15
- stdio MCP server for everything else; identical retrieval behavior on each
16
- - **Tiered routing** — optional, preferred, forced, or off, per capability;
17
- forced refuses when exclusivity is impossible
18
- - **Plan-then-apply installer** — every write previewed as old → new before
19
- touching disk; arrays merge instead of replacing; uninstall reverses
20
- exactly what was applied
21
- - **Trap-aware detection** — catches what the agents' own docs don't warn
22
- about: Codex's silent `[tools] web_search` no-op, Pi's codemode hiding MCP
23
- tools; conflicting rules and web-capable servers surface in the plan, and
24
- `init` notes a Codex release that drifts from the tested lock
25
- - **Git-safe installs** — the key never enters config files
26
- (`${DEEPSEEK_API_KEY}` indirection or `env_vars`), so a project-scope
27
- install commits clean
28
- - **Fails loudly, never falls back** — no silent provider switches;
29
- localhost and private URLs blocked before they leave the machine
15
+ - **One package, three hosts** — a native OpenCode v2 plugin, a native Pi extension,
16
+ and a stdio MCP server for Codex, all sharing one retrieval core
17
+ - **Routing control per tool** — search and fetch are set independently to optional,
18
+ preferred, forced, or off; the tier table in Usage explains each
19
+ - **Review before anything is written** — `init` prints the full plan and writes only
20
+ with `--apply`; uninstall restores from snapshots while preserving edits you made
21
+ afterwards
22
+ - **Knows the host's web landscape** — detects conflicting web tools and rules,
23
+ configures Pi's MCP fallback for direct tool exposure, and reports Codex version
24
+ drift
25
+ - **Your key never enters a config file** — installs reference the environment
26
+ (`${DEEPSEEK_API_KEY}` indirection or `env_vars`), so a project-scope install
27
+ commits clean
28
+ - **Fails loudly, never switches silently** — no fallback to another provider, and
29
+ localhost/private URLs are blocked before a request leaves the machine
30
30
 
31
31
  ## Usage
32
32
 
33
- Shipped adapters:
33
+ Choose your host:
34
34
 
35
- - [OpenCode v2 setup and usage](docs/agents/opencode-v2.md) — native plugin API
36
- - [Pi setup and usage](docs/agents/pi.md) — native extension API (MCP fallback)
37
- - [Codex setup and usage](docs/agents/codex.md) — MCP server over stdio
35
+ | Host | Default integration | Setup |
36
+ | --- | --- | --- |
37
+ | OpenCode v2 | Native plugin: search provider and Fetch tools | [OpenCode guide](docs/agents/opencode-v2.md) |
38
+ | Pi | Native extension: Search and Fetch tools; MCP also available | [Pi guide](docs/agents/pi.md) |
39
+ | Codex | MCP server over stdio, with readable text results | [Codex guide](docs/agents/codex.md) |
38
40
 
39
- The MCP server works with any host that supports MCP tools over stdio. The
40
- `deepseek-web-retrieval init` CLI installs it with plan-then-apply semantics — search and
41
- fetch tiers chosen per capability, project or global scope, snapshots for rollback. For
42
- how coding agents integrate—native websearch providers, native fetch tools, MCP, or
43
- wrappers—see the
44
- [integration model](docs/integration.md) with its version-locked host support matrix, the
45
- [control-level research](docs/research/control-matrix.md), and the
46
- [MCP compatibility research](docs/research/mcp-compatibility.md). A host is listed as supported
47
- only after an adapter and guide exist.
41
+ The installer CLI requires Node.js 20+ and npm. Retrieval requires a DeepSeek API key
42
+ with access to Search and Fetch and sufficient account balance. Set `DEEPSEEK_API_KEY`
43
+ in the environment that launches your host; OpenCode can also use its stored DeepSeek key.
44
+
45
+ Run the command for your host to preview a configuration:
46
+
47
+ ```bash
48
+ # OpenCode: select DeepSeek as the search provider and prefer its Fetch tool.
49
+ npx deepseek-web-retrieval init --host opencode --scope project --search forced --fetch preferred
50
+
51
+ # Pi: use the native extension and prefer both tools.
52
+ npx deepseek-web-retrieval init --host pi --scope project --search preferred --fetch preferred
53
+
54
+ # Codex: register the MCP server and prefer both tools.
55
+ npx deepseek-web-retrieval init --host codex --scope global --search preferred --fetch preferred
56
+ ```
57
+
58
+ `--search` and `--fetch` each pick a tier — how strongly the host steers toward the
59
+ DeepSeek tool, chosen independently per capability:
60
+
61
+ | Tier | Effect |
62
+ | --- | --- |
63
+ | `optional` | The tool is declared; the model picks freely among its web tools |
64
+ | `preferred` | Rules files steer the model toward the DeepSeek tool — probable, not guaranteed |
65
+ | `forced` | Built-in competitors are disabled or replaced so routing is deterministic; the installer refuses rather than pretend when a host cannot guarantee it |
66
+ | `off` | The capability is not installed |
67
+
68
+ A preview run writes nothing. It prints the complete plan — every file it would touch
69
+ and every old value → new value:
70
+
71
+ ```console
72
+ $ npx deepseek-web-retrieval init --host codex --scope global --search preferred --fetch preferred
73
+ Install plan: codex (global scope)
74
+ Tiers: search=preferred, fetch=preferred
75
+
76
+ Files:
77
+ ~/.codex/config.toml
78
+ set mcp_servers.deepseek = {"command":"npx","args":["-y","deepseek-web-retrieval"],"env_vars":["DEEPSEEK_API_KEY","DEEPSEEK_... (was (absent))
79
+ ~/.codex/AGENTS.md
80
+ upsert marked rules block
81
+
82
+ Notes:
83
+ - Codex stdio children do not inherit the parent environment, so the entry forwards DEEPSEEK_API_KEY and every DEEPSEEK_* option variable explicitly via env_vars; shell-set knobs reach the server without hand-editing config.toml (the shared config file works without any forwarding).
84
+ - Rules block upserted in ~/.codex/AGENTS.md; Codex reads ~/.codex/AGENTS.md plus every AGENTS.md from the project root to the cwd.
85
+ - Shared config ownership is recorded in ~/.codex/.config.toml.deepseek-web-retrieval.codex.owner.json; uninstall releases it. Keep this local metadata with the config.
86
+
87
+ Plan only — re-run with --apply to write these changes.
88
+ ```
89
+
90
+ Repeat your chosen command with `--apply` to write the plan. The host guides explain
91
+ activation steps and per-host tier limits. Pi defaults to the extension path; add
92
+ `--path mcp` to use its MCP fallback. Add `--pin` to register the exact version of the
93
+ CLI you are running (`deepseek-web-retrieval@<version>`) instead of the unpinned name,
94
+ so hosts keep resolving that release rather than every latest publish — reproducible
95
+ setups trade away auto-updates; re-run `init --pin` from a newer CLI to move the pin.
96
+
97
+ Other stdio MCP hosts may use the server, but the supported setup guides and installer
98
+ currently cover the three hosts above. See the [integration model](docs/integration.md)
99
+ for tested versions and the [control tiers](docs/research/control-matrix.md) for routing
100
+ limits. For an existing installation, follow the
101
+ [upgrade instructions](docs/integration.md#upgrading-existing-installs).
48
102
 
49
103
  For shared search, fetch, retry, and privacy behavior, see below.
50
104
 
@@ -60,13 +114,19 @@ binary files, per-request billing) are documented there.
60
114
  - Requests summaries only (`need_content: false`, `summary` falling back to `snippet`);
61
115
  full page content never enters the results.
62
116
  - Returns at most ten results by default (matching the API's `count` default and the
63
- industry norm for AI-native search APIs), deduplicating URLs. Optional
64
- `rerank_score` and `authority` thresholds are off by default — the default
65
- returns exactly what DeepSeek ranked, including results without a score;
66
- when a positive threshold is set, results below it (or without a score to
67
- compare) are dropped.
117
+ industry norm for AI-native search APIs), deduplicating URLs.
118
+ - Optional `rerank_score` and `authority` thresholds are off by default — the default
119
+ returns exactly what DeepSeek ranked, including results without a score. A positive
120
+ `rerank_score` threshold drops results below it and results without a score; a positive
121
+ `authority` threshold drops known authorities below it, while results with an unknown
122
+ authority stay unless `allowUnknownAuthority` is set to false.
68
123
  - Builds `blockedDomains`, `includeDomains`, and `language` into query operators and
69
124
  rejects the final query locally when it exceeds the API's 128-character limit.
125
+ - On the paths where this package defines the search tool's inputs (the MCP server and
126
+ the Pi extension), the tool accepts an optional `original_question` — the user's
127
+ question in their own words — forwarded as DeepSeek's `ori_question`, trimmed and
128
+ truncated to the API's 128 characters; a blank input on the Pi extension falls back
129
+ to the most recent user message in the session.
70
130
  - An empty result set is normal and is not an error.
71
131
 
72
132
  ### Fetch
@@ -83,9 +143,10 @@ binary files, per-request billing) are documented there.
83
143
 
84
144
  ### Timeouts and retries
85
145
 
86
- Request timeouts include reading the response body. Retryable responses are 408, 425, 429,
87
- and 5xx; `Retry-After` is honored up to 10 seconds. Other failures, including 401, timeouts,
88
- and network errors, fail without retrying.
146
+ Request timeouts include reading the response body. Transient failures are retried twice
147
+ by default (0–5, `maxRetries`); retryable responses are 408, 425, 429, and 5xx, and
148
+ `Retry-After` is honored up to 10 seconds. Other failures, including 401, timeouts, and
149
+ network errors, fail without retrying.
89
150
 
90
151
  ### No automatic fallback
91
152
 
@@ -99,6 +160,66 @@ Queries and URLs are sent to `https://api.deepseek.com`; the API key is sent onl
99
160
  Bearer token to DeepSeek and to nothing else. Retrieval is billed per successful request —
100
161
  see the official docs for pricing and rate limits before enabling a team deployment.
101
162
 
163
+ ## Configuration
164
+
165
+ Every knob resolves through one chain, low → high, identically on every host:
166
+ `built-in defaults < shared config file < DEEPSEEK_* environment < host-native config`
167
+ — a higher layer always wins, so nothing already configured loses effect.
168
+
169
+ The shared file — `$XDG_CONFIG_HOME/deepseek-web-retrieval/config.json`, default
170
+ `~/.config/deepseek-web-retrieval/config.json` on Linux and macOS and
171
+ `%APPDATA%\deepseek-web-retrieval\config.json` on Windows (an explicitly set
172
+ `XDG_CONFIG_HOME` still wins there) — works on every host and uses the
173
+ camelCase option keys:
174
+
175
+ ```json
176
+ {
177
+ "count": 20,
178
+ "blockedDomains": ["pinterest.com"],
179
+ "language": "zh",
180
+ "searchLocalization": "203.0.113.7"
181
+ }
182
+ ```
183
+
184
+ Unknown keys and host-integration keys are warned about on stderr and ignored. The
185
+ API key does not go in the file — it keeps its existing channels (`DEEPSEEK_API_KEY`
186
+ in the environment, or OpenCode's stored credential).
187
+
188
+ Knobs fall into three classes; the shared file carries the first two:
189
+
190
+ | Knob class | Shared file | Examples |
191
+ | --- | --- | --- |
192
+ | API behavior — the user↔DeepSeek relationship | yes — that is the point of the file | `count`, `blockedDomains`, `language`, `maxRetries` |
193
+ | Host-sensitive — interacts with host output caps and deadlines | carries the safe defaults; a host layer is the recommended override point | `searchTimeoutMs`, `fetchTimeoutMs`, `fetchMaxChars`, `maxSummaryChars` |
194
+ | Host integration — the host's tool landscape | rejected — warned about and ignored | `searchEnabled`, `setDefaultWebsearch`, `apiKeySource` |
195
+
196
+ The same knob has two names — the camelCase key for the shared file and OpenCode's
197
+ options, the `DEEPSEEK_*` variable for the environment:
198
+
199
+ | Shared file / OpenCode options | Environment |
200
+ | --- | --- |
201
+ | `count` | `DEEPSEEK_SEARCH_COUNT` |
202
+ | `blockedDomains` | `DEEPSEEK_SEARCH_BLOCKED_DOMAINS` |
203
+ | `language` | `DEEPSEEK_SEARCH_LANGUAGE` |
204
+ | `searchLocalization` | `DEEPSEEK_SEARCH_LOCALIZATION` |
205
+ | `fetchMaxChars` | `DEEPSEEK_FETCH_MAX_CHARS` |
206
+ | `maxRetries` | `DEEPSEEK_MAX_RETRIES` |
207
+
208
+ The full per-knob mapping is documented side by side in each guide's option table;
209
+ per-host mechanics — how the environment reaches a stdio server, each host's output
210
+ caps and deadlines — live there too: [Codex](docs/agents/codex.md),
211
+ [Pi](docs/agents/pi.md), [OpenCode](docs/agents/opencode-v2.md). Keep
212
+ host-independent intent in the shared file; prefer a host layer when a
213
+ host-sensitive knob would cross its host's cap or deadline.
214
+
215
+ To see what actually resolves, run `npx deepseek-web-retrieval config`: every knob
216
+ printed with its value and its source (`default`, `file`, or `env`), plus any problems
217
+ in the file or in `DEEPSEEK_*` variables (unknown names, unusable values) replayed as
218
+ visible warnings — it exits 1 when there are problems, so it doubles as a dotfile CI
219
+ check. `npx deepseek-web-retrieval config --search "<query>"`
220
+ runs one billed search through the effective configuration to verify the key, config,
221
+ and network end to end.
222
+
102
223
  ## Development
103
224
 
104
225
  ```bash
@@ -107,9 +228,10 @@ bun run check
107
228
  ```
108
229
 
109
230
  Use `bun run lint:fix` to apply Biome's safe lint fixes and formatting. See
110
- [CONTRIBUTING.md](CONTRIBUTING.md) for the development checks and e2e scenarios.
231
+ [CONTRIBUTING.md](CONTRIBUTING.md) for development checks, e2e scenarios, and
232
+ [automated tag releases](CONTRIBUTING.md#automated-releases).
111
233
 
112
- The test suite mocks the DeepSeek HTTP API and the OpenCode plugin host, and drives the
234
+ The test suite mocks the DeepSeek HTTP API and the OpenCode and Pi host APIs, and drives the
113
235
  MCP server with SDK clients pinned to each supported protocol revision. Real API calls
114
236
  require a funded DeepSeek account. Shared retrieval logic lives in `src/core/`; adapters
115
237
  live in `src/<agent>/` (the cross-host MCP server lives in `src/mcp/`). Adapter docs live