deepseek-web-retrieval 0.5.0 → 0.6.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.
package/dist/cli.js CHANGED
@@ -15,12 +15,11 @@ var __export = (target, all) => {
15
15
  };
16
16
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
17
 
18
- // src/core/constants.ts
19
- var SEARCH_ENDPOINT = "https://api.deepseek.com/v1/tools/search", FETCH_ENDPOINT = "https://api.deepseek.com/v1/tools/fetch", DEFAULT_SEARCH_COUNT = 10, DEFAULT_MAX_RESULTS = 10, DEFAULT_MIN_RERANK = 0, DEFAULT_MIN_AUTHORITY = 0, DEFAULT_MAX_SUMMARY_CHARS = 1200, DEFAULT_FETCH_MAX_CHARS = 16000, DEFAULT_TIMEOUT_MS = 30000, MIN_TIMEOUT_MS = 1000, MAX_TIMEOUT_MS = 120000, MAX_QUERY_CHARS = 128, MAX_URL_CHARS = 8192, MAX_ERROR_BODY_CHARS = 2000, MAX_RESPONSE_BYTES, FETCH_TRUNCATION_MARKER = `
20
-
21
- [content truncated]`, DEFAULT_API_KEY_SOURCE = "auto", DEFAULT_MAX_RETRIES = 0, MAX_RETRIES = 5, DEFAULT_RETRY_BASE_DELAY_MS = 250, MAX_RETRY_DELAY_MS = 1e4, API_KEY_ENV = "DEEPSEEK_API_KEY", ENABLE_SEARCH_ENV = "DEEPSEEK_ENABLE_SEARCH", ENABLE_FETCH_ENV = "DEEPSEEK_ENABLE_FETCH";
22
- var init_constants = __esm(() => {
23
- MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
18
+ // src/version.ts
19
+ import { readFileSync } from "node:fs";
20
+ var TOOL_VERSION;
21
+ var init_version = __esm(() => {
22
+ TOOL_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
24
23
  });
25
24
 
26
25
  // src/installer/persistence.ts
@@ -32,7 +31,7 @@ import {
32
31
  lstatSync,
33
32
  mkdirSync,
34
33
  openSync,
35
- readFileSync,
34
+ readFileSync as readFileSync2,
36
35
  realpathSync,
37
36
  renameSync,
38
37
  rmSync,
@@ -66,7 +65,7 @@ function atomicWrite(file, text, mode) {
66
65
  try {
67
66
  fd = openSync(temporary, "wx", 384);
68
67
  writeFileSync(fd, text);
69
- if (readFileSync(temporary, "utf8") !== text)
68
+ if (readFileSync2(temporary, "utf8") !== text)
70
69
  throw new Error(`Incomplete write to ${file}`);
71
70
  fchmodSync(fd, mode ?? existingMode ?? 438 & ~process.umask());
72
71
  fsyncSync(fd);
@@ -806,10 +805,10 @@ function parse(text, errors = [], options = ParseOptions.DEFAULT) {
806
805
  }
807
806
  const visitor = {
808
807
  onObjectBegin: () => {
809
- const object2 = {};
810
- onValue(object2);
808
+ const object = {};
809
+ onValue(object);
811
810
  previousParents.push(currentParent);
812
- currentParent = object2;
811
+ currentParent = object;
813
812
  currentProperty = null;
814
813
  },
815
814
  onObjectProperty: (name) => {
@@ -1506,11 +1505,11 @@ function appendEntries(existing, entries, path) {
1506
1505
  var init_value = () => {};
1507
1506
 
1508
1507
  // src/installer/formats/json.ts
1509
- import { existsSync, readFileSync as readFileSync2 } from "node:fs";
1508
+ import { existsSync, readFileSync as readFileSync3 } from "node:fs";
1510
1509
  function loadJson(file) {
1511
1510
  if (!existsSync(file))
1512
1511
  return { exists: false, text: "", value: {}, lossy: false };
1513
- const text = readFileSync2(file, "utf8");
1512
+ const text = readFileSync3(file, "utf8");
1514
1513
  try {
1515
1514
  return { exists: true, text, value: parseJsonc(text), lossy: false };
1516
1515
  } catch (error) {
@@ -1642,7 +1641,7 @@ var init_json = __esm(() => {
1642
1641
  });
1643
1642
 
1644
1643
  // src/installer/formats/rules.ts
1645
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
1644
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
1646
1645
  function rulesMarkers(host) {
1647
1646
  return {
1648
1647
  begin: `<!-- deepseek-web-retrieval:${host}:rules:begin -->`,
@@ -1697,7 +1696,7 @@ function rulesCodec(host) {
1697
1696
  format: "rules",
1698
1697
  load: (file) => {
1699
1698
  const exists = existsSync2(file);
1700
- const text = exists ? readFileSync3(file, "utf8") : "";
1699
+ const text = exists ? readFileSync4(file, "utf8") : "";
1701
1700
  try {
1702
1701
  blockRange(host, text);
1703
1702
  return { exists, text, value: {}, lossy: false };
@@ -1718,12 +1717,12 @@ function rulesCodec(host) {
1718
1717
  var init_rules = () => {};
1719
1718
 
1720
1719
  // node_modules/smol-toml/dist/error.js
1721
- function getLineColFromPtr(string2, ptr) {
1722
- let lines = string2.slice(0, ptr).split(/\r?\n/);
1720
+ function getLineColFromPtr(string, ptr) {
1721
+ let lines = string.slice(0, ptr).split(/\r?\n/);
1723
1722
  return [lines.length, lines.pop().length + 1];
1724
1723
  }
1725
- function makeCodeBlock(string2, line, column) {
1726
- let lines = string2.split(/\r?\n/);
1724
+ function makeCodeBlock(string, line, column) {
1725
+ let lines = string.split(/\r?\n/);
1727
1726
  let codeblock = "";
1728
1727
  let numberLen = (Math.log10(line + 1) | 0) + 1;
1729
1728
  for (let i = line - 1;i <= line + 1; i++) {
@@ -2905,11 +2904,11 @@ var init_dist = __esm(() => {
2905
2904
  });
2906
2905
 
2907
2906
  // src/installer/formats/toml.ts
2908
- import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
2907
+ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
2909
2908
  function loadToml(file) {
2910
2909
  if (!existsSync3(file))
2911
2910
  return { exists: false, text: "", value: {}, lossy: false };
2912
- const text = readFileSync4(file, "utf8");
2911
+ const text = readFileSync5(file, "utf8");
2913
2912
  try {
2914
2913
  return { exists: true, text, value: parse3(text), lossy: hasTomlComment(text) };
2915
2914
  } catch (error) {
@@ -3082,7 +3081,7 @@ var init_formats = __esm(() => {
3082
3081
  });
3083
3082
 
3084
3083
  // src/installer/revert.ts
3085
- import { existsSync as existsSync4, readFileSync as readFileSync5, rmdirSync, unlinkSync } from "node:fs";
3084
+ import { existsSync as existsSync4, readFileSync as readFileSync6, rmdirSync, unlinkSync } from "node:fs";
3086
3085
  import { dirname as dirname2 } from "node:path";
3087
3086
  function pruneEmptyDir(dir) {
3088
3087
  try {
@@ -3096,7 +3095,7 @@ function revertRecordedFile(file, host, opts) {
3096
3095
  return lines;
3097
3096
  }
3098
3097
  const codec = codecFor(file.format, host);
3099
- const text = readFileSync5(file.file, "utf8");
3098
+ const text = readFileSync6(file.file, "utf8");
3100
3099
  if (file.format === "rules") {
3101
3100
  const edit2 = { file: file.file, format: "rules", block: file.blockApplied ?? "" };
3102
3101
  if (!codec.verify(text, edit2)) {
@@ -3145,16 +3144,16 @@ function stateDir(roots, scope) {
3145
3144
  var init_paths = () => {};
3146
3145
 
3147
3146
  // src/installer/state.ts
3148
- import { existsSync as existsSync5, lstatSync as lstatSync2, readdirSync, readFileSync as readFileSync6, rmSync as rmSync2 } from "node:fs";
3147
+ import { existsSync as existsSync5, lstatSync as lstatSync2, readdirSync, readFileSync as readFileSync7, rmSync as rmSync2 } from "node:fs";
3149
3148
  import { isAbsolute, join as join3 } from "node:path";
3150
- import { z as z2 } from "zod/v4";
3149
+ import { z } from "zod/v4";
3151
3150
  function statePathFor(input) {
3152
3151
  return join3(stateDir(input, input.scope), `install.${input.host}.json`);
3153
3152
  }
3154
3153
  function readRecordFile(file, host, scope) {
3155
3154
  let text;
3156
3155
  try {
3157
- text = readFileSync6(file, "utf8");
3156
+ text = readFileSync7(file, "utf8");
3158
3157
  } catch (error) {
3159
3158
  if (error.code === "ENOENT") {
3160
3159
  try {
@@ -3241,31 +3240,32 @@ var keyPath, tier, operation, recordSchema, InstallRecordError;
3241
3240
  var init_state = __esm(() => {
3242
3241
  init_paths();
3243
3242
  init_persistence();
3244
- keyPath = z2.array(z2.string().min(1)).min(1);
3245
- tier = z2.enum(["optional", "preferred", "forced", "off"]);
3246
- operation = z2.discriminatedUnion("op", [
3247
- z2.object({ op: z2.literal("set"), path: keyPath, applied: z2.unknown(), previous: z2.unknown().optional() }),
3248
- z2.object({
3249
- op: z2.literal("append-array"),
3243
+ keyPath = z.array(z.string().min(1)).min(1);
3244
+ tier = z.enum(["optional", "preferred", "forced", "off"]);
3245
+ operation = z.discriminatedUnion("op", [
3246
+ z.object({ op: z.literal("set"), path: keyPath, applied: z.unknown(), previous: z.unknown().optional() }),
3247
+ z.object({
3248
+ op: z.literal("append-array"),
3250
3249
  path: keyPath,
3251
- applied: z2.array(z2.unknown()),
3252
- previous: z2.unknown().optional()
3250
+ applied: z.array(z.unknown()),
3251
+ previous: z.unknown().optional()
3253
3252
  })
3254
3253
  ]);
3255
- recordSchema = z2.object({
3256
- version: z2.literal(1),
3257
- host: z2.enum(["opencode", "pi", "codex"]),
3258
- scope: z2.enum(["global", "project"]),
3259
- tiers: z2.object({ search: tier, fetch: tier }),
3260
- createdAt: z2.string().refine((value) => Number.isFinite(Date.parse(value))),
3261
- files: z2.array(z2.object({
3262
- file: z2.string().refine(isAbsolute),
3263
- format: z2.enum(["json", "toml", "rules"]),
3264
- created: z2.boolean(),
3265
- shared: z2.literal(true).optional(),
3266
- ops: z2.array(operation),
3267
- blockApplied: z2.string().optional(),
3268
- createdParents: z2.array(keyPath).optional()
3254
+ recordSchema = z.object({
3255
+ version: z.literal(1),
3256
+ installerVersion: z.string().optional(),
3257
+ host: z.enum(["opencode", "pi", "codex"]),
3258
+ scope: z.enum(["global", "project"]),
3259
+ tiers: z.object({ search: tier, fetch: tier }),
3260
+ createdAt: z.string().refine((value) => Number.isFinite(Date.parse(value))),
3261
+ files: z.array(z.object({
3262
+ file: z.string().refine(isAbsolute),
3263
+ format: z.enum(["json", "toml", "rules"]),
3264
+ created: z.boolean(),
3265
+ shared: z.literal(true).optional(),
3266
+ ops: z.array(operation),
3267
+ blockApplied: z.string().optional(),
3268
+ createdParents: z.array(keyPath).optional()
3269
3269
  }))
3270
3270
  });
3271
3271
  InstallRecordError = class InstallRecordError extends Error {
@@ -3281,7 +3281,7 @@ var init_state = __esm(() => {
3281
3281
  });
3282
3282
 
3283
3283
  // src/installer/ownership.ts
3284
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync7, realpathSync as realpathSync2, rmSync as rmSync3, writeFileSync as writeFileSync2 } from "node:fs";
3284
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync8, realpathSync as realpathSync2, rmSync as rmSync3, writeFileSync as writeFileSync2 } from "node:fs";
3285
3285
  import { basename as basename2, dirname as dirname3, join as join4, resolve } from "node:path";
3286
3286
  function canonicalPath(file) {
3287
3287
  const absolute = resolve(file);
@@ -3304,7 +3304,7 @@ function readOwner(file) {
3304
3304
  if (!existsSync6(file))
3305
3305
  return;
3306
3306
  try {
3307
- const value = JSON.parse(readFileSync7(file, "utf8"));
3307
+ const value = JSON.parse(readFileSync8(file, "utf8"));
3308
3308
  if (isPlainObject(value) && typeof value.recordPath === "string" && typeof value.cwd === "string" && (value.scope === "project" || value.scope === "global")) {
3309
3309
  return { recordPath: value.recordPath, cwd: value.cwd, scope: value.scope };
3310
3310
  }
@@ -3418,7 +3418,7 @@ var init_operation_lock = __esm(() => {
3418
3418
  });
3419
3419
 
3420
3420
  // src/installer/apply.ts
3421
- import { existsSync as existsSync7, readFileSync as readFileSync8, rmSync as rmSync5 } from "node:fs";
3421
+ import { existsSync as existsSync7, readFileSync as readFileSync9, rmSync as rmSync5 } from "node:fs";
3422
3422
  import { dirname as dirname5 } from "node:path";
3423
3423
  function applyPlan(plan, input) {
3424
3424
  if (plan.errors.length > 0) {
@@ -3456,6 +3456,7 @@ function applyLocked(plan, input) {
3456
3456
  lines.push(...verification.lines);
3457
3457
  const record = {
3458
3458
  version: 1,
3459
+ installerVersion: TOOL_VERSION,
3459
3460
  host: plan.host,
3460
3461
  scope: plan.scope,
3461
3462
  tiers: plan.tiers,
@@ -3483,7 +3484,7 @@ function applyLocked(plan, input) {
3483
3484
  } catch (error) {
3484
3485
  throw new ApplyError("recovery_required", `apply was written and verified, but old config ownership could not be released (${errorMessage(error)}). ` + "The new install record is retained; repair the reported ownership metadata before re-running init.", error);
3485
3486
  }
3486
- return { lines, ok: true };
3487
+ return { lines };
3487
3488
  }
3488
3489
  function errorMessage(error) {
3489
3490
  return error instanceof Error ? error.message : String(error);
@@ -3515,7 +3516,7 @@ function snapshotTouchedFiles(plan) {
3515
3516
  const snapshots = new Map;
3516
3517
  const touched = [...plan.edits.map((edit2) => edit2.file), ...(plan.reverts ?? []).map((revert) => revert.file)];
3517
3518
  for (const file of new Set(touched)) {
3518
- snapshots.set(file, existsSync7(file) ? { exists: true, text: readFileSync8(file, "utf8") } : { exists: false, text: "" });
3519
+ snapshots.set(file, existsSync7(file) ? { exists: true, text: readFileSync9(file, "utf8") } : { exists: false, text: "" });
3519
3520
  }
3520
3521
  return snapshots;
3521
3522
  }
@@ -3525,10 +3526,10 @@ function rollbackApply(input, previous, snapshots) {
3525
3526
  for (const [file, snapshot] of [...snapshots.entries()].reverse()) {
3526
3527
  try {
3527
3528
  if (snapshot.exists) {
3528
- if (existsSync7(file) && readFileSync8(file, "utf8") === snapshot.text)
3529
+ if (existsSync7(file) && readFileSync9(file, "utf8") === snapshot.text)
3529
3530
  continue;
3530
3531
  writeConfig(file, snapshot.text);
3531
- if (readFileSync8(file, "utf8") !== snapshot.text)
3532
+ if (readFileSync9(file, "utf8") !== snapshot.text)
3532
3533
  throw new Error("restored contents differ from the snapshot");
3533
3534
  } else {
3534
3535
  if (!existsSync7(file))
@@ -3621,7 +3622,7 @@ function verifyEdits(edits, host) {
3621
3622
  continue;
3622
3623
  }
3623
3624
  const codec = codecFor(edit2.format, host);
3624
- const text = readFileSync8(edit2.file, "utf8");
3625
+ const text = readFileSync9(edit2.file, "utf8");
3625
3626
  if (edit2.format === "rules") {
3626
3627
  const good = codec.verify(text, edit2);
3627
3628
  lines.push(`${good ? "pass" : "FAIL"} ${edit2.file}: rules block ${good ? "present" : "missing"}`);
@@ -3643,6 +3644,7 @@ function describeOp(op) {
3643
3644
  }
3644
3645
  var ApplyError;
3645
3646
  var init_apply = __esm(() => {
3647
+ init_version();
3646
3648
  init_formats();
3647
3649
  init_value();
3648
3650
  init_operation_lock();
@@ -3659,8 +3661,16 @@ var init_apply = __esm(() => {
3659
3661
  };
3660
3662
  });
3661
3663
 
3664
+ // src/core/constants.ts
3665
+ var SEARCH_ENDPOINT = "https://api.deepseek.com/v1/tools/search", FETCH_ENDPOINT = "https://api.deepseek.com/v1/tools/fetch", DEFAULT_SEARCH_COUNT = 10, DEFAULT_MAX_RESULTS = 10, DEFAULT_MIN_RERANK = 0, DEFAULT_MIN_AUTHORITY = 0, DEFAULT_MAX_SUMMARY_CHARS = 1200, DEFAULT_FETCH_MAX_CHARS = 16000, DEFAULT_TIMEOUT_MS = 30000, MIN_TIMEOUT_MS = 1000, MAX_TIMEOUT_MS = 120000, MAX_QUERY_CHARS = 128, MAX_URL_CHARS = 8192, MAX_ERROR_BODY_CHARS = 2000, MAX_RESPONSE_BYTES, FETCH_TRUNCATION_MARKER = `
3666
+
3667
+ [content truncated]`, DEFAULT_API_KEY_SOURCE = "auto", DEFAULT_MAX_RETRIES = 0, MAX_RETRIES = 5, DEFAULT_RETRY_BASE_DELAY_MS = 250, MAX_RETRY_DELAY_MS = 1e4, API_KEY_ENV = "DEEPSEEK_API_KEY", ENABLE_SEARCH_ENV = "DEEPSEEK_ENABLE_SEARCH", ENABLE_FETCH_ENV = "DEEPSEEK_ENABLE_FETCH";
3668
+ var init_constants = __esm(() => {
3669
+ MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
3670
+ });
3671
+
3662
3672
  // src/installer/detect.ts
3663
- import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
3673
+ import { existsSync as existsSync8, readFileSync as readFileSync10 } from "node:fs";
3664
3674
  function replacingExistingEntryNote(path) {
3665
3675
  return `An existing ${path} entry is being replaced; its previous form is recorded for uninstall.`;
3666
3676
  }
@@ -3685,7 +3695,7 @@ function findCompetitorSteering(host, file) {
3685
3695
  return [];
3686
3696
  let text;
3687
3697
  try {
3688
- text = readFileSync9(file, "utf8");
3698
+ text = readFileSync10(file, "utf8");
3689
3699
  } catch {
3690
3700
  return [];
3691
3701
  }
@@ -4452,7 +4462,8 @@ var init_uninstall = __esm(() => {
4452
4462
  // src/installer/cli.ts
4453
4463
  var exports_cli = {};
4454
4464
  __export(exports_cli, {
4455
- runInstallerCli: () => runInstallerCli
4465
+ runInstallerCli: () => runInstallerCli,
4466
+ exitCodeForError: () => exitCodeForError
4456
4467
  });
4457
4468
  import { homedir } from "node:os";
4458
4469
  import { resolve as resolve2 } from "node:path";
@@ -4473,6 +4484,10 @@ function parseFlags(args) {
4473
4484
  problems.push(`--${name} does not accept a value; use --${name} to enable it or omit it`);
4474
4485
  continue;
4475
4486
  }
4487
+ if (booleans.has(name)) {
4488
+ problems.push(`--${name} was given more than once`);
4489
+ continue;
4490
+ }
4476
4491
  booleans.add(name);
4477
4492
  continue;
4478
4493
  }
@@ -4480,6 +4495,10 @@ function parseFlags(args) {
4480
4495
  problems.push(`unknown flag --${name}`);
4481
4496
  continue;
4482
4497
  }
4498
+ if (values.has(name)) {
4499
+ problems.push(`--${name} was given more than once`);
4500
+ continue;
4501
+ }
4483
4502
  if (eq !== -1) {
4484
4503
  values.set(name, arg.slice(eq + 1));
4485
4504
  continue;
@@ -4498,9 +4517,17 @@ async function runInstallerCli(argv, io = {}) {
4498
4517
  const out = io.out ?? ((line) => console.log(line));
4499
4518
  const err = io.err ?? ((line) => console.error(line));
4500
4519
  const [command, ...rest] = argv;
4501
- if (command === undefined || command === "help" || command === "--help") {
4520
+ if (command === "version" || command === "--version") {
4521
+ out(TOOL_VERSION);
4522
+ return 0;
4523
+ }
4524
+ if (command === undefined) {
4525
+ err(USAGE);
4526
+ return EXIT_USAGE;
4527
+ }
4528
+ if (command === "help" || command === "--help") {
4502
4529
  out(USAGE);
4503
- return command === undefined ? 1 : 0;
4530
+ return 0;
4504
4531
  }
4505
4532
  const flags = parseFlags(rest);
4506
4533
  if (flags.problems.length > 0) {
@@ -4508,7 +4535,7 @@ async function runInstallerCli(argv, io = {}) {
4508
4535
  err(`error: ${problem}`);
4509
4536
  err(`
4510
4537
  ${USAGE}`);
4511
- return 1;
4538
+ return EXIT_USAGE;
4512
4539
  }
4513
4540
  const cwd = resolve2(flags.values.get("cwd") ?? process.cwd());
4514
4541
  const home = process.env.HOME ?? homedir();
@@ -4526,7 +4553,8 @@ ${USAGE}`);
4526
4553
  return 0;
4527
4554
  }
4528
4555
  for (const record of records) {
4529
- out(`${record.host} (${record.scope}) — search=${record.tiers.search}, fetch=${record.tiers.fetch}, installed ${record.createdAt}`);
4556
+ const by = record.installerVersion ? ` by v${record.installerVersion}` : "";
4557
+ out(`${record.host} (${record.scope}) — search=${record.tiers.search}, fetch=${record.tiers.fetch}, installed ${record.createdAt}${by}`);
4530
4558
  for (const file of record.files)
4531
4559
  out(` ${file.created ? "created" : "modified"} ${file.file}`);
4532
4560
  }
@@ -4549,7 +4577,7 @@ ${USAGE}`);
4549
4577
  err(`Unknown command "${command}".
4550
4578
 
4551
4579
  ${USAGE}`);
4552
- return 1;
4580
+ return EXIT_USAGE;
4553
4581
  }
4554
4582
  const required = requireInput(flags, cwd, home, configHome2, true);
4555
4583
  if (!required.ok)
@@ -4574,18 +4602,21 @@ Plan only — re-run with --apply to write these changes.`);
4574
4602
  const result = applyPlan(plan, input);
4575
4603
  for (const line of result.lines)
4576
4604
  out(line);
4577
- return result.ok ? 0 : 1;
4605
+ return 0;
4578
4606
  } catch (error) {
4579
4607
  err(error instanceof Error ? error.message : String(error));
4580
- return 1;
4608
+ return exitCodeForError(error);
4581
4609
  }
4582
4610
  }
4611
+ function exitCodeForError(error) {
4612
+ return error instanceof ApplyError && error.status === "recovery_required" ? EXIT_RECOVERY : EXIT_FAILURE;
4613
+ }
4583
4614
  function usageError(problems, err) {
4584
4615
  for (const problem of problems)
4585
4616
  err(`error: ${problem}`);
4586
4617
  err(`
4587
4618
  ${USAGE}`);
4588
- return 1;
4619
+ return EXIT_USAGE;
4589
4620
  }
4590
4621
  function resolveConfigHome(home) {
4591
4622
  const xdg = process.env.XDG_CONFIG_HOME;
@@ -4642,8 +4673,9 @@ function requireInput(flags, cwd, home, configHome2, needsTiers) {
4642
4673
  }
4643
4674
  };
4644
4675
  }
4645
- var HOSTS, HOST_CHOICES, SCOPES, TIERS, USAGE, VALUE_FLAGS, BOOLEAN_FLAGS, PATH_CHOICES;
4676
+ var HOSTS, HOST_CHOICES, SCOPES, TIERS, EXIT_FAILURE = 1, EXIT_USAGE = 2, EXIT_RECOVERY = 3, USAGE, VALUE_FLAGS, BOOLEAN_FLAGS, PATH_CHOICES;
4646
4677
  var init_cli = __esm(() => {
4678
+ init_version();
4647
4679
  init_apply();
4648
4680
  init_hosts();
4649
4681
  init_state();
@@ -4656,6 +4688,7 @@ var init_cli = __esm(() => {
4656
4688
  deepseek-web-retrieval init --host ${HOST_CHOICES} --scope <project|global> --search <optional|preferred|forced|off> --fetch <optional|preferred|forced|off> [--path <extension|mcp>] [--package <npm ref>] [--cwd <dir>] [--apply]
4657
4689
  deepseek-web-retrieval uninstall --host ${HOST_CHOICES} --scope <project|global> [--cwd <dir>]
4658
4690
  deepseek-web-retrieval list [--cwd <dir>]
4691
+ deepseek-web-retrieval version
4659
4692
 
4660
4693
  init prints the full plan (every file, old value → new value) and writes nothing
4661
4694
  until --apply is passed. uninstall restores what the plan applied. --path picks
@@ -4663,27 +4696,25 @@ the integration mechanism for hosts with more than one (Pi: extension by
4663
4696
  default, mcp for the stdio MCP server). --package overrides the package ref
4664
4697
  written into host config; the Pi extension path turns it into the packages
4665
4698
  source (a bare name is prefixed with npm:, a ref that already starts with npm:
4666
- is written as-is).`;
4699
+ is written as-is).
4700
+
4701
+ Exit codes: 0 success; 1 refused or failed with nothing written (a failed apply
4702
+ is fully rolled back); 2 invalid command line; 3 recovery required — a failed
4703
+ apply could not roll back completely, follow the reported guidance before
4704
+ re-running.`;
4667
4705
  VALUE_FLAGS = new Set(["host", "scope", "search", "fetch", "path", "package", "cwd"]);
4668
4706
  BOOLEAN_FLAGS = new Set(["apply"]);
4669
4707
  PATH_CHOICES = ["extension", "mcp"];
4670
4708
  });
4671
4709
 
4672
- // src/mcp/cli.ts
4673
- import { serveStdio } from "@modelcontextprotocol/server/stdio";
4674
-
4675
4710
  // src/core/auth.ts
4676
- init_constants();
4677
4711
  function apiKeyFromEnv(env = process.env) {
4678
4712
  const key = env[API_KEY_ENV]?.trim();
4679
4713
  return key ? key : undefined;
4680
4714
  }
4681
-
4682
- // src/core/env.ts
4683
- init_constants();
4684
-
4685
- // src/core/options.ts
4686
- init_constants();
4715
+ var init_auth = __esm(() => {
4716
+ init_constants();
4717
+ });
4687
4718
 
4688
4719
  // src/core/domains.ts
4689
4720
  import { isIP } from "node:net";
@@ -4791,6 +4822,7 @@ function ipv4FromIpv6Hextets(value, pattern) {
4791
4822
  return;
4792
4823
  return `${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`;
4793
4824
  }
4825
+ var init_domains = () => {};
4794
4826
 
4795
4827
  // src/core/options.ts
4796
4828
  function resolvePluginOptions(input) {
@@ -4851,35 +4883,12 @@ function clampInt(value, fallback, min, max) {
4851
4883
  const number = typeof value === "number" && Number.isFinite(value) ? Math.trunc(value) : fallback;
4852
4884
  return Math.min(max, Math.max(min, number));
4853
4885
  }
4886
+ var init_options = __esm(() => {
4887
+ init_constants();
4888
+ init_domains();
4889
+ });
4854
4890
 
4855
4891
  // src/core/env.ts
4856
- var NUMBER_ENV = {
4857
- count: "DEEPSEEK_SEARCH_COUNT",
4858
- maxResults: "DEEPSEEK_SEARCH_MAX_RESULTS",
4859
- minRerank: "DEEPSEEK_SEARCH_MIN_RERANK",
4860
- minAuthority: "DEEPSEEK_SEARCH_MIN_AUTHORITY",
4861
- maxSummaryChars: "DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS",
4862
- searchTimeoutMs: "DEEPSEEK_SEARCH_TIMEOUT_MS",
4863
- fetchMaxChars: "DEEPSEEK_FETCH_MAX_CHARS",
4864
- fetchTimeoutMs: "DEEPSEEK_FETCH_TIMEOUT_MS",
4865
- maxRetries: "DEEPSEEK_MAX_RETRIES",
4866
- retryBaseDelayMs: "DEEPSEEK_RETRY_BASE_DELAY_MS"
4867
- };
4868
- var TEXT_ENV = {
4869
- language: "DEEPSEEK_SEARCH_LANGUAGE"
4870
- };
4871
- var DOMAINS_ENV = {
4872
- blockedDomains: "DEEPSEEK_SEARCH_BLOCKED_DOMAINS",
4873
- includeDomains: "DEEPSEEK_SEARCH_INCLUDE_DOMAINS",
4874
- fetchAllowedDomains: "DEEPSEEK_FETCH_ALLOWED_DOMAINS",
4875
- fetchBlockedDomains: "DEEPSEEK_FETCH_BLOCKED_DOMAINS"
4876
- };
4877
- var FALSE_ONLY_ENV = {
4878
- allowUnknownAuthority: "DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY",
4879
- fetchBlockPrivateHosts: "DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS",
4880
- searchEnabled: ENABLE_SEARCH_ENV,
4881
- fetchEnabled: ENABLE_FETCH_ENV
4882
- };
4883
4892
  function resolveEnvOptions(env = process.env) {
4884
4893
  return resolvePluginOptions(pluginOptionsFromEnv(env));
4885
4894
  }
@@ -4941,20 +4950,55 @@ function isFalseValue(value) {
4941
4950
  const trimmed = value?.trim().toLowerCase();
4942
4951
  return trimmed === "false" || trimmed === "0" || trimmed === "no" || trimmed === "off";
4943
4952
  }
4953
+ var NUMBER_ENV, TEXT_ENV, DOMAINS_ENV, FALSE_ONLY_ENV;
4954
+ var init_env = __esm(() => {
4955
+ init_constants();
4956
+ init_options();
4957
+ NUMBER_ENV = {
4958
+ count: "DEEPSEEK_SEARCH_COUNT",
4959
+ maxResults: "DEEPSEEK_SEARCH_MAX_RESULTS",
4960
+ minRerank: "DEEPSEEK_SEARCH_MIN_RERANK",
4961
+ minAuthority: "DEEPSEEK_SEARCH_MIN_AUTHORITY",
4962
+ maxSummaryChars: "DEEPSEEK_SEARCH_MAX_SUMMARY_CHARS",
4963
+ searchTimeoutMs: "DEEPSEEK_SEARCH_TIMEOUT_MS",
4964
+ fetchMaxChars: "DEEPSEEK_FETCH_MAX_CHARS",
4965
+ fetchTimeoutMs: "DEEPSEEK_FETCH_TIMEOUT_MS",
4966
+ maxRetries: "DEEPSEEK_MAX_RETRIES",
4967
+ retryBaseDelayMs: "DEEPSEEK_RETRY_BASE_DELAY_MS"
4968
+ };
4969
+ TEXT_ENV = {
4970
+ language: "DEEPSEEK_SEARCH_LANGUAGE"
4971
+ };
4972
+ DOMAINS_ENV = {
4973
+ blockedDomains: "DEEPSEEK_SEARCH_BLOCKED_DOMAINS",
4974
+ includeDomains: "DEEPSEEK_SEARCH_INCLUDE_DOMAINS",
4975
+ fetchAllowedDomains: "DEEPSEEK_FETCH_ALLOWED_DOMAINS",
4976
+ fetchBlockedDomains: "DEEPSEEK_FETCH_BLOCKED_DOMAINS"
4977
+ };
4978
+ FALSE_ONLY_ENV = {
4979
+ allowUnknownAuthority: "DEEPSEEK_SEARCH_ALLOW_UNKNOWN_AUTHORITY",
4980
+ fetchBlockPrivateHosts: "DEEPSEEK_FETCH_BLOCK_PRIVATE_HOSTS",
4981
+ searchEnabled: ENABLE_SEARCH_ENV,
4982
+ fetchEnabled: ENABLE_FETCH_ENV
4983
+ };
4984
+ });
4944
4985
 
4945
4986
  // src/mcp/auth.ts
4946
- init_constants();
4947
- var MISSING_API_KEY_MESSAGE = `DeepSeek API key not found. Set ${API_KEY_ENV} in the MCP server's env configuration.`;
4948
4987
  function requireApiKey(env) {
4949
4988
  const apiKey = apiKeyFromEnv(env);
4950
4989
  if (!apiKey)
4951
4990
  throw new Error(MISSING_API_KEY_MESSAGE);
4952
4991
  return apiKey;
4953
4992
  }
4993
+ var MISSING_API_KEY_MESSAGE;
4994
+ var init_auth2 = __esm(() => {
4995
+ init_auth();
4996
+ init_constants();
4997
+ MISSING_API_KEY_MESSAGE = `DeepSeek API key not found. Set ${API_KEY_ENV} in the MCP server's env configuration.`;
4998
+ });
4954
4999
 
4955
5000
  // src/mcp/client.ts
4956
5001
  import { CLIENT_INFO_META_KEY } from "@modelcontextprotocol/server";
4957
- var JSON_REPLACING_CLIENT_NAMES = new Set(["codex-mcp-client"]);
4958
5002
  function clientNameOf(server, ctx) {
4959
5003
  const envelope = ctx.mcpReq.envelope;
4960
5004
  const name = envelope?.[CLIENT_INFO_META_KEY];
@@ -4969,119 +5013,119 @@ function isJsonReplacingClient(name) {
4969
5013
  function omitStructuredContent(server, ctx) {
4970
5014
  return isJsonReplacingClient(clientNameOf(server, ctx));
4971
5015
  }
5016
+ var JSON_REPLACING_CLIENT_NAMES;
5017
+ var init_client = __esm(() => {
5018
+ JSON_REPLACING_CLIENT_NAMES = new Set(["codex-mcp-client"]);
5019
+ });
4972
5020
 
4973
- // src/mcp/server.ts
4974
- import { McpServer } from "@modelcontextprotocol/server";
4975
- import * as z from "zod/v4";
4976
5021
  // package.json
4977
- var package_default = {
4978
- $schema: "https://json.schemastore.org/package.json",
4979
- name: "deepseek-web-retrieval",
4980
- version: "0.5.0",
4981
- description: "Token-efficient DeepSeek Search and Fetch for coding agents, starting with OpenCode v2.",
4982
- type: "module",
4983
- license: "MIT",
4984
- repository: {
4985
- type: "git",
4986
- url: "git+https://github.com/gwokhou/deepseek-web-retrieval.git"
4987
- },
4988
- homepage: "https://github.com/gwokhou/deepseek-web-retrieval#readme",
4989
- bugs: "https://github.com/gwokhou/deepseek-web-retrieval/issues",
4990
- keywords: [
4991
- "opencode",
4992
- "opencode-plugin",
4993
- "pi",
4994
- "pi-extension",
4995
- "deepseek",
4996
- "websearch",
4997
- "webfetch",
4998
- "coding-agent",
4999
- "mcp"
5000
- ],
5001
- exports: {
5002
- ".": "./index.ts",
5003
- "./core": "./src/core/index.ts",
5004
- "./mcp": "./src/mcp/server.ts",
5005
- "./pi": "./src/pi/extension.ts"
5006
- },
5007
- pi: {
5008
- extensions: [
5009
- "./src/pi/extension.ts"
5010
- ]
5011
- },
5012
- bin: {
5013
- "deepseek-web-retrieval": "dist/cli.js"
5014
- },
5015
- files: [
5016
- "index.ts",
5017
- "src",
5018
- "dist",
5019
- "docs",
5020
- "README.md",
5021
- "LICENSE",
5022
- "CHANGELOG.md",
5023
- "examples"
5024
- ],
5025
- scripts: {
5026
- lint: "biome check --error-on-warnings .",
5027
- "lint:ci": "biome ci --error-on-warnings .",
5028
- "lint:fix": "biome check --write --error-on-warnings .",
5029
- format: "biome format --write .",
5030
- typecheck: "tsc --noEmit",
5031
- build: "bun build src/mcp/cli.ts --target=node --format=esm --outdir=dist --external @modelcontextprotocol/server --external @modelcontextprotocol/server/stdio --external zod --external zod/v4",
5032
- prepublishOnly: "bun run check:release",
5033
- test: "bun test",
5034
- "test:package": "node scripts/test-package.mjs",
5035
- "test:e2e:keyless": "bun run test:e2e pi pi-extension installer reinit upgrade pkg capability-off",
5036
- "check:release": "bun run check && bun run test:package && bun run test:e2e:keyless",
5037
- "test:e2e": "bun run test/e2e/run.ts",
5038
- "docs:matrix": "bun run scripts/render-matrix.ts",
5039
- "test:coverage": "bun test --coverage",
5040
- check: "bun run lint && bun run typecheck && bun run docs:matrix --check && bun run build && bun test"
5041
- },
5042
- peerDependencies: {
5043
- "@earendil-works/pi-ai": "^1.3.0",
5044
- "@earendil-works/pi-coding-agent": "^1.3.0",
5045
- "@opencode/plugin": "^2.0.32"
5046
- },
5047
- peerDependenciesMeta: {
5048
- "@earendil-works/pi-ai": {
5049
- optional: true
5022
+ var package_default;
5023
+ var init_package = __esm(() => {
5024
+ package_default = {
5025
+ $schema: "https://json.schemastore.org/package.json",
5026
+ name: "deepseek-web-retrieval",
5027
+ version: "0.6.0",
5028
+ description: "Token-efficient DeepSeek Search and Fetch for coding agents, starting with OpenCode v2.",
5029
+ type: "module",
5030
+ license: "MIT",
5031
+ repository: {
5032
+ type: "git",
5033
+ url: "git+https://github.com/gwokhou/deepseek-web-retrieval.git"
5050
5034
  },
5051
- "@earendil-works/pi-coding-agent": {
5052
- optional: true
5035
+ homepage: "https://github.com/gwokhou/deepseek-web-retrieval#readme",
5036
+ bugs: "https://github.com/gwokhou/deepseek-web-retrieval/issues",
5037
+ keywords: [
5038
+ "opencode",
5039
+ "opencode-plugin",
5040
+ "pi",
5041
+ "pi-extension",
5042
+ "deepseek",
5043
+ "websearch",
5044
+ "webfetch",
5045
+ "coding-agent",
5046
+ "mcp"
5047
+ ],
5048
+ exports: {
5049
+ ".": "./index.ts",
5050
+ "./core": "./src/core/index.ts",
5051
+ "./mcp": "./src/mcp/server.ts",
5052
+ "./pi": "./src/pi/extension.ts"
5053
5053
  },
5054
- "@opencode/plugin": {
5055
- optional: true
5056
- }
5057
- },
5058
- devDependencies: {
5059
- "@biomejs/biome": "2.5.15",
5060
- "@earendil-works/pi-ai": "1.3.0",
5061
- "@earendil-works/pi-coding-agent": "1.3.0",
5062
- "@modelcontextprotocol/client": "^2.3.1",
5063
- "@opencode/plugin": "2.0.32",
5064
- "@types/bun": "1.4.0",
5065
- "@types/node": "^26.6.5",
5066
- typescript: "5.9.3"
5067
- },
5068
- engines: {
5069
- bun: ">=1.3.0",
5070
- node: ">=20"
5071
- },
5072
- dependencies: {
5073
- "@modelcontextprotocol/server": "^2.3.1",
5074
- "jsonc-parser": "^3.3.1",
5075
- "smol-toml": "^1.9.1",
5076
- zod: "^4"
5077
- }
5078
- };
5079
-
5080
- // src/core/client.ts
5081
- init_constants();
5054
+ pi: {
5055
+ extensions: [
5056
+ "./src/pi/extension.ts"
5057
+ ]
5058
+ },
5059
+ bin: {
5060
+ "deepseek-web-retrieval": "dist/cli.js"
5061
+ },
5062
+ files: [
5063
+ "index.ts",
5064
+ "src",
5065
+ "dist",
5066
+ "docs",
5067
+ "README.md",
5068
+ "LICENSE",
5069
+ "CHANGELOG.md",
5070
+ "examples"
5071
+ ],
5072
+ scripts: {
5073
+ lint: "biome check --error-on-warnings .",
5074
+ "lint:ci": "biome ci --error-on-warnings .",
5075
+ "lint:fix": "biome check --write --error-on-warnings .",
5076
+ format: "biome format --write .",
5077
+ typecheck: "tsc --noEmit",
5078
+ build: "bun build src/mcp/cli.ts --target=node --format=esm --outdir=dist --external @modelcontextprotocol/server --external @modelcontextprotocol/server/stdio --external zod --external zod/v4",
5079
+ prepublishOnly: "bun run check:release",
5080
+ test: "bun test",
5081
+ "test:package": "node scripts/test-package.mjs",
5082
+ "test:e2e:keyless": "bun run test:e2e pi pi-extension installer reinit upgrade pkg capability-off",
5083
+ "check:release": "bun run check && bun run test:package && bun run test:e2e:keyless",
5084
+ "test:e2e": "bun run test/e2e/run.ts",
5085
+ "docs:matrix": "bun run scripts/render-matrix.ts",
5086
+ "test:coverage": "bun test --coverage",
5087
+ check: "bun run lint && bun run typecheck && bun run docs:matrix --check && bun run build && bun test"
5088
+ },
5089
+ peerDependencies: {
5090
+ "@earendil-works/pi-ai": "^1.3.0",
5091
+ "@earendil-works/pi-coding-agent": "^1.3.0",
5092
+ "@opencode/plugin": "^2.0.32"
5093
+ },
5094
+ peerDependenciesMeta: {
5095
+ "@earendil-works/pi-ai": {
5096
+ optional: true
5097
+ },
5098
+ "@earendil-works/pi-coding-agent": {
5099
+ optional: true
5100
+ },
5101
+ "@opencode/plugin": {
5102
+ optional: true
5103
+ }
5104
+ },
5105
+ devDependencies: {
5106
+ "@biomejs/biome": "2.5.15",
5107
+ "@earendil-works/pi-ai": "1.3.0",
5108
+ "@earendil-works/pi-coding-agent": "1.3.0",
5109
+ "@modelcontextprotocol/client": "^2.3.1",
5110
+ "@opencode/plugin": "2.0.32",
5111
+ "@types/bun": "1.4.0",
5112
+ "@types/node": "^26.6.5",
5113
+ typescript: "5.9.3"
5114
+ },
5115
+ engines: {
5116
+ bun: ">=1.3.0",
5117
+ node: ">=20"
5118
+ },
5119
+ dependencies: {
5120
+ "@modelcontextprotocol/server": "^2.3.1",
5121
+ "jsonc-parser": "^3.3.1",
5122
+ "smol-toml": "^1.9.1",
5123
+ zod: "^4"
5124
+ }
5125
+ };
5126
+ });
5082
5127
 
5083
5128
  // src/core/format.ts
5084
- init_constants();
5085
5129
  function truncate(value, maxChars) {
5086
5130
  if (maxChars <= 0)
5087
5131
  return "";
@@ -5127,16 +5171,16 @@ function normalizeHeading(value) {
5127
5171
  function redactSecrets(value) {
5128
5172
  return value.replace(/\bsk-[A-Za-z0-9_-]{8,}\b/g, "sk-***").replace(/\bBearer\s+[A-Za-z0-9._~+/=-]{8,}/gi, "Bearer ***");
5129
5173
  }
5130
- function formatApiError(operation, status, body) {
5174
+ function formatApiError(operation2, status, body) {
5131
5175
  const detail = redactSecrets(body.trim());
5132
5176
  const detailChars = Array.from(detail);
5133
5177
  const text = detail ? detailChars.length > MAX_ERROR_BODY_CHARS ? `${detailChars.slice(0, MAX_ERROR_BODY_CHARS).join("")}…` : detail : "empty response body";
5134
5178
  const hint = status === 401 ? "invalid API key" : status === 402 ? "insufficient balance" : status === 403 ? "permission denied" : status === 429 ? "rate limited" : undefined;
5135
- const label = hint ? `${operation} failed (HTTP ${status}, ${hint})` : `${operation} failed (HTTP ${status})`;
5179
+ const label = hint ? `${operation2} failed (HTTP ${status}, ${hint})` : `${operation2} failed (HTTP ${status})`;
5136
5180
  return `${label}: ${text}`;
5137
5181
  }
5138
- function formatTimeoutError(operation, timeoutMs) {
5139
- return `${operation} timed out after ${timeoutMs} ms`;
5182
+ function formatTimeoutError(operation2, timeoutMs) {
5183
+ return `${operation2} timed out after ${timeoutMs} ms`;
5140
5184
  }
5141
5185
  function formatSearchResults(results) {
5142
5186
  if (results.length === 0)
@@ -5171,9 +5215,11 @@ function escapeBrackets(value) {
5171
5215
  function formatPublished(epochMs) {
5172
5216
  return new Date(epochMs).toISOString().slice(0, 10);
5173
5217
  }
5218
+ var init_format2 = __esm(() => {
5219
+ init_constants();
5220
+ });
5174
5221
 
5175
5222
  // src/core/url.ts
5176
- init_constants();
5177
5223
  function parseFetchUrl(value) {
5178
5224
  const input = value.trim();
5179
5225
  if (!input)
@@ -5215,6 +5261,10 @@ function normalizeResultUrl(value) {
5215
5261
  return;
5216
5262
  }
5217
5263
  }
5264
+ var init_url = __esm(() => {
5265
+ init_constants();
5266
+ init_domains();
5267
+ });
5218
5268
 
5219
5269
  // src/core/search.ts
5220
5270
  function buildQuery(query, options) {
@@ -5280,33 +5330,20 @@ function optionalText2(value) {
5280
5330
  const trimmed = value.trim();
5281
5331
  return trimmed ? trimmed : undefined;
5282
5332
  }
5333
+ var init_search = __esm(() => {
5334
+ init_domains();
5335
+ init_format2();
5336
+ init_url();
5337
+ });
5283
5338
 
5284
5339
  // src/core/transport.ts
5285
- init_constants();
5286
- class DeepSeekApiError extends Error {
5287
- operation;
5288
- status;
5289
- body;
5290
- retryable;
5291
- retryAfterMs;
5292
- constructor(input) {
5293
- const body = redactSecrets(input.body);
5294
- super(formatApiError(input.operation, input.status, body));
5295
- this.name = "DeepSeekApiError";
5296
- this.operation = input.operation;
5297
- this.status = input.status;
5298
- this.body = body;
5299
- this.retryable = input.status === 408 || input.status === 425 || input.status === 429 || input.status >= 500 && input.status <= 599;
5300
- this.retryAfterMs = input.retryAfterMs;
5301
- }
5302
- }
5303
- async function postJson(endpoint, body, operation, opts) {
5340
+ async function postJson(endpoint, body, operation2, opts) {
5304
5341
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
5305
5342
  const attempts = opts.retry.maxRetries + 1;
5306
5343
  let lastError;
5307
5344
  for (let attempt = 0;attempt < attempts; attempt++) {
5308
5345
  try {
5309
- return await requestOnce(endpoint, body, operation, opts, fetchImpl);
5346
+ return await requestOnce(endpoint, body, operation2, opts, fetchImpl);
5310
5347
  } catch (error) {
5311
5348
  lastError = error;
5312
5349
  if (!(error instanceof DeepSeekApiError) || !error.retryable || attempt === attempts - 1) {
@@ -5317,7 +5354,7 @@ async function postJson(endpoint, body, operation, opts) {
5317
5354
  }
5318
5355
  throw lastError;
5319
5356
  }
5320
- async function requestOnce(endpoint, body, operation, opts, fetchImpl) {
5357
+ async function requestOnce(endpoint, body, operation2, opts, fetchImpl) {
5321
5358
  return fetchWithTimeout(endpoint, {
5322
5359
  method: "POST",
5323
5360
  headers: {
@@ -5325,27 +5362,27 @@ async function requestOnce(endpoint, body, operation, opts, fetchImpl) {
5325
5362
  "Content-Type": "application/json"
5326
5363
  },
5327
5364
  body: JSON.stringify(body)
5328
- }, opts.signal, opts.timeoutMs, operation, fetchImpl, async (response) => {
5365
+ }, opts.signal, opts.timeoutMs, operation2, fetchImpl, async (response) => {
5329
5366
  if (!response.ok) {
5330
5367
  const text2 = await readBoundedText(response, MAX_ERROR_BODY_CHARS);
5331
5368
  throw new DeepSeekApiError({
5332
- operation,
5369
+ operation: operation2,
5333
5370
  status: response.status,
5334
5371
  body: text2,
5335
5372
  retryAfterMs: parseRetryAfter(response.headers.get("retry-after"))
5336
5373
  });
5337
5374
  }
5338
- const text = await readResponseText(response, MAX_RESPONSE_BYTES, operation);
5375
+ const text = await readResponseText(response, MAX_RESPONSE_BYTES, operation2);
5339
5376
  if (!text.trim())
5340
- throw new Error(`${operation} returned an empty response body`);
5377
+ throw new Error(`${operation2} returned an empty response body`);
5341
5378
  try {
5342
5379
  return JSON.parse(text);
5343
5380
  } catch {
5344
- throw new Error(`${operation} returned invalid JSON: ${truncate(redactSecrets(text), 500)}`);
5381
+ throw new Error(`${operation2} returned invalid JSON: ${truncate(redactSecrets(text), 500)}`);
5345
5382
  }
5346
5383
  });
5347
5384
  }
5348
- async function fetchWithTimeout(endpoint, init, signal, timeoutMs, operation, fetchImpl, handleResponse) {
5385
+ async function fetchWithTimeout(endpoint, init, signal, timeoutMs, operation2, fetchImpl, handleResponse) {
5349
5386
  const controller = new AbortController;
5350
5387
  let timedOut = false;
5351
5388
  const forwardAbort = () => controller.abort(signal.reason);
@@ -5362,9 +5399,9 @@ async function fetchWithTimeout(endpoint, init, signal, timeoutMs, operation, fe
5362
5399
  return await handleResponse(response);
5363
5400
  } catch (error) {
5364
5401
  if (timedOut)
5365
- throw new Error(formatTimeoutError(operation, timeoutMs));
5402
+ throw new Error(formatTimeoutError(operation2, timeoutMs));
5366
5403
  if (signal.aborted)
5367
- throw abortReason(signal, operation);
5404
+ throw abortReason(signal, operation2);
5368
5405
  throw error;
5369
5406
  } finally {
5370
5407
  if (timer !== undefined)
@@ -5394,10 +5431,10 @@ function retryDelay(retryAfterMs, baseDelayMs, attempt) {
5394
5431
  function sleep(ms, signal) {
5395
5432
  if (ms <= 0)
5396
5433
  return Promise.resolve();
5397
- return new Promise((resolve, reject) => {
5434
+ return new Promise((resolve3, reject) => {
5398
5435
  const timer = setTimeout(() => {
5399
5436
  signal.removeEventListener("abort", onAbort);
5400
- resolve();
5437
+ resolve3();
5401
5438
  }, ms);
5402
5439
  const onAbort = () => {
5403
5440
  clearTimeout(timer);
@@ -5411,8 +5448,8 @@ function sleep(ms, signal) {
5411
5448
  signal.addEventListener("abort", onAbort, { once: true });
5412
5449
  });
5413
5450
  }
5414
- function abortReason(signal, operation) {
5415
- return signal.reason instanceof Error ? signal.reason : new Error(`${operation} request aborted`);
5451
+ function abortReason(signal, operation2) {
5452
+ return signal.reason instanceof Error ? signal.reason : new Error(`${operation2} request aborted`);
5416
5453
  }
5417
5454
  async function readBoundedText(response, maxChars) {
5418
5455
  if (!response.body)
@@ -5440,11 +5477,11 @@ async function readBoundedText(response, maxChars) {
5440
5477
  }
5441
5478
  return truncate(text, limit);
5442
5479
  }
5443
- async function readResponseText(response, maxBytes, operation) {
5480
+ async function readResponseText(response, maxBytes, operation2) {
5444
5481
  if (!response.body) {
5445
5482
  const text2 = await response.text();
5446
5483
  if (new TextEncoder().encode(text2).byteLength > maxBytes) {
5447
- throw new Error(`${operation} response exceeded ${maxBytes} bytes`);
5484
+ throw new Error(`${operation2} response exceeded ${maxBytes} bytes`);
5448
5485
  }
5449
5486
  return text2;
5450
5487
  }
@@ -5459,7 +5496,7 @@ async function readResponseText(response, maxBytes, operation) {
5459
5496
  break;
5460
5497
  bytes += value.byteLength;
5461
5498
  if (bytes > maxBytes) {
5462
- throw new Error(`${operation} response exceeded ${maxBytes} bytes`);
5499
+ throw new Error(`${operation2} response exceeded ${maxBytes} bytes`);
5463
5500
  }
5464
5501
  text += decoder.decode(value, { stream: true });
5465
5502
  }
@@ -5472,6 +5509,28 @@ async function readResponseText(response, maxBytes, operation) {
5472
5509
  }
5473
5510
  return text;
5474
5511
  }
5512
+ var DeepSeekApiError;
5513
+ var init_transport = __esm(() => {
5514
+ init_constants();
5515
+ init_format2();
5516
+ DeepSeekApiError = class DeepSeekApiError extends Error {
5517
+ operation;
5518
+ status;
5519
+ body;
5520
+ retryable;
5521
+ retryAfterMs;
5522
+ constructor(input) {
5523
+ const body = redactSecrets(input.body);
5524
+ super(formatApiError(input.operation, input.status, body));
5525
+ this.name = "DeepSeekApiError";
5526
+ this.operation = input.operation;
5527
+ this.status = input.status;
5528
+ this.body = body;
5529
+ this.retryable = input.status === 408 || input.status === 425 || input.status === 429 || input.status >= 500 && input.status <= 599;
5530
+ this.retryAfterMs = input.retryAfterMs;
5531
+ }
5532
+ };
5533
+ });
5475
5534
 
5476
5535
  // src/core/client.ts
5477
5536
  function effectiveTimeout(configuredMs, perCallMs) {
@@ -5535,30 +5594,28 @@ function createRetrievalClient(dependencies = {}) {
5535
5594
  fetchDocument: (url, options, request) => fetchDocument(url, options, bind(request))
5536
5595
  };
5537
5596
  }
5538
- var retrievalClient = createRetrievalClient();
5539
-
5540
- // src/mcp/server.ts
5541
- init_constants();
5597
+ var retrievalClient;
5598
+ var init_client2 = __esm(() => {
5599
+ init_constants();
5600
+ init_domains();
5601
+ init_format2();
5602
+ init_search();
5603
+ init_transport();
5604
+ init_url();
5605
+ init_transport();
5606
+ retrievalClient = createRetrievalClient();
5607
+ });
5542
5608
 
5543
5609
  // src/core/descriptions.ts
5544
- var FETCH_SERVICE_LIMITS = "DeepSeek does not render JavaScript and cannot reach private networks; PDFs, images, and other binary files are unsupported.";
5545
- var FETCH_OUTPUT_TRUNCATED = "Output is truncated to the configured size.";
5546
- var SEARCH_RANKED_FILTERED = "Results are ranked by relevance and source authority, deduplicated by URL, and capped at the configured maximum.";
5547
- var SEARCH_EMPTY_IS_NORMAL = "An empty result list is normal, not an error.";
5548
- var SEARCH_QUERY_OPERATORS = "Use site:/-site: operators in the query to include or exclude domains; the full query must stay within 128 characters.";
5549
- var SEARCH_TOOL_DESCRIPTION = "Search the web with DeepSeek's in-house search engine and return a short, filtered result " + "list (title, URL, summary). " + `${SEARCH_RANKED_FILTERED} ` + `${SEARCH_EMPTY_IS_NORMAL} ` + `${SEARCH_QUERY_OPERATORS} ` + "To read a full page, pass a result URL to the deepseek_fetch tool.";
5550
- var FETCH_TOOL_DESCRIPTION = "Fetch one web page as clean Markdown through DeepSeek's Fetch API. " + `${FETCH_SERVICE_LIMITS} ` + `${FETCH_OUTPUT_TRUNCATED}`;
5551
- var SEARCH_QUERY_PARAMETER = "Search query, 128 characters or fewer including operators (site:, -site:, quoted phrases, lang:).";
5552
- var FETCH_URL_PARAMETER = "Absolute http:// or https:// URL to fetch. Credentials are rejected.";
5610
+ var FETCH_SERVICE_LIMITS = "DeepSeek does not render JavaScript and cannot reach private networks; PDFs, images, and other binary files are unsupported.", FETCH_OUTPUT_TRUNCATED = "Output is truncated to the configured size.", SEARCH_RANKED_FILTERED = "Results are ranked by relevance and source authority, deduplicated by URL, and capped at the configured maximum.", SEARCH_EMPTY_IS_NORMAL = "An empty result list is normal, not an error.", SEARCH_QUERY_OPERATORS = "Use site:/-site: operators in the query to include or exclude domains; the full query must stay within 128 characters.", SEARCH_TOOL_DESCRIPTION, FETCH_TOOL_DESCRIPTION, SEARCH_QUERY_PARAMETER = "Search query, 128 characters or fewer including operators (site:, -site:, quoted phrases, lang:).", FETCH_URL_PARAMETER = "Absolute http:// or https:// URL to fetch. Credentials are rejected.";
5611
+ var init_descriptions = __esm(() => {
5612
+ SEARCH_TOOL_DESCRIPTION = "Search the web with DeepSeek's in-house search engine and return a short, filtered result " + "list (title, URL, summary). " + `${SEARCH_RANKED_FILTERED} ` + `${SEARCH_EMPTY_IS_NORMAL} ` + `${SEARCH_QUERY_OPERATORS} ` + "To read a full page, pass a result URL to the deepseek_fetch tool.";
5613
+ FETCH_TOOL_DESCRIPTION = "Fetch one web page as clean Markdown through DeepSeek's Fetch API. " + `${FETCH_SERVICE_LIMITS} ` + `${FETCH_OUTPUT_TRUNCATED}`;
5614
+ });
5553
5615
 
5554
5616
  // src/mcp/server.ts
5555
- var MCP_SERVER_NAME = "deepseek-web-retrieval";
5556
- var SEARCH_INPUT = z.object({
5557
- query: z.string().min(1).describe(SEARCH_QUERY_PARAMETER)
5558
- });
5559
- var FETCH_INPUT = z.object({
5560
- url: z.string().min(1).describe(FETCH_URL_PARAMETER)
5561
- });
5617
+ import { McpServer } from "@modelcontextprotocol/server";
5618
+ import * as z2 from "zod/v4";
5562
5619
  function createDeepSeekServer(config, env = process.env, client = retrievalClient) {
5563
5620
  const server = new McpServer({ name: MCP_SERVER_NAME, version: package_default.version });
5564
5621
  if (config.search.enabled) {
@@ -5619,38 +5676,71 @@ function toErrorResult(error) {
5619
5676
  const message = error instanceof Error ? error.message : String(error);
5620
5677
  return { content: [{ type: "text", text: message }], isError: true };
5621
5678
  }
5679
+ var MCP_SERVER_NAME = "deepseek-web-retrieval", SEARCH_INPUT, FETCH_INPUT;
5680
+ var init_server = __esm(() => {
5681
+ init_package();
5682
+ init_client2();
5683
+ init_constants();
5684
+ init_descriptions();
5685
+ init_format2();
5686
+ init_auth2();
5687
+ init_client();
5688
+ SEARCH_INPUT = z2.object({
5689
+ query: z2.string().min(1).describe(SEARCH_QUERY_PARAMETER)
5690
+ });
5691
+ FETCH_INPUT = z2.object({
5692
+ url: z2.string().min(1).describe(FETCH_URL_PARAMETER)
5693
+ });
5694
+ });
5695
+
5696
+ // src/mcp/serve.ts
5697
+ var exports_serve = {};
5698
+ __export(exports_serve, {
5699
+ serveMcp: () => serveMcp
5700
+ });
5701
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
5702
+ function serveMcp() {
5703
+ const env = process.env;
5704
+ if (!apiKeyFromEnv(env)) {
5705
+ console.error(MISSING_API_KEY_MESSAGE);
5706
+ process.exit(1);
5707
+ }
5708
+ const config = resolveEnvOptions(env);
5709
+ const precheck = servePrecheck(config);
5710
+ if (precheck) {
5711
+ console.error(precheck);
5712
+ process.exit(1);
5713
+ }
5714
+ const handle = serveStdio(() => {
5715
+ const server = createDeepSeekServer(config, env);
5716
+ server.server.oninitialized = () => {
5717
+ const info = server.server.getClientVersion();
5718
+ if (info === undefined)
5719
+ return;
5720
+ console.error(`mcp client: ${info.name} ${info.version ?? "unknown"} — ` + (isJsonReplacingClient(info.name) ? "text-only results (this client replaces content with serialized structuredContent)" : "text + structuredContent results"));
5721
+ };
5722
+ return server;
5723
+ });
5724
+ const tools = [
5725
+ config.search.enabled ? `search (max ${config.search.maxResults} results)` : null,
5726
+ config.fetch.enabled ? `fetch (max ${config.fetch.maxChars} chars)` : null
5727
+ ].filter(Boolean).join(", ");
5728
+ console.error(`deepseek-web-retrieval MCP server on stdio (${tools})`);
5729
+ process.on("SIGINT", () => void handle.close());
5730
+ process.on("SIGTERM", () => void handle.close());
5731
+ }
5732
+ var init_serve = __esm(() => {
5733
+ init_auth();
5734
+ init_env();
5735
+ init_auth2();
5736
+ init_client();
5737
+ init_server();
5738
+ });
5622
5739
 
5623
5740
  // src/mcp/cli.ts
5624
- var subcommand = process.argv[2];
5625
- if (subcommand === "init" || subcommand === "uninstall" || subcommand === "list") {
5741
+ if (process.argv.length > 2) {
5626
5742
  const { runInstallerCli: runInstallerCli2 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
5627
5743
  process.exit(await runInstallerCli2(process.argv.slice(2)));
5628
5744
  }
5629
- var env = process.env;
5630
- if (!apiKeyFromEnv(env)) {
5631
- console.error(MISSING_API_KEY_MESSAGE);
5632
- process.exit(1);
5633
- }
5634
- var config = resolveEnvOptions(env);
5635
- var precheck = servePrecheck(config);
5636
- if (precheck) {
5637
- console.error(precheck);
5638
- process.exit(1);
5639
- }
5640
- var handle = serveStdio(() => {
5641
- const server = createDeepSeekServer(config, env);
5642
- server.server.oninitialized = () => {
5643
- const info = server.server.getClientVersion();
5644
- if (info === undefined)
5645
- return;
5646
- console.error(`mcp client: ${info.name} ${info.version ?? "unknown"} — ` + (isJsonReplacingClient(info.name) ? "text-only results (this client replaces content with serialized structuredContent)" : "text + structuredContent results"));
5647
- };
5648
- return server;
5649
- });
5650
- var tools = [
5651
- config.search.enabled ? `search (max ${config.search.maxResults} results)` : null,
5652
- config.fetch.enabled ? `fetch (max ${config.fetch.maxChars} chars)` : null
5653
- ].filter(Boolean).join(", ");
5654
- console.error(`deepseek-web-retrieval MCP server on stdio (${tools})`);
5655
- process.on("SIGINT", () => void handle.close());
5656
- process.on("SIGTERM", () => void handle.close());
5745
+ var { serveMcp: serveMcp2 } = await Promise.resolve().then(() => (init_serve(), exports_serve));
5746
+ serveMcp2();