dsh-web-tavily 0.4.1 → 0.4.2
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/CHANGELOG.md +15 -0
- package/README.md +39 -9
- package/README.zh.md +29 -5
- package/dsh-plugin.json +1 -1
- package/lib/diag.js +6 -2
- package/lib/index.js +22 -5
- package/package.json +19 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.4.2 (2026-09-16)
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **`ipaddr.js` is a declared dependency now.** `lib/index.js` imported it while `package.json` declared no `dependencies` at all, so the import resolved only because the dsh installation closure happens to hoist it (it is a dependency of `@deepseek-ai/dsh-web-fetch-http`). It is a module-scope import, so a closure without it would have failed the plugin tree. Declared as `^2.5.0`.
|
|
10
|
+
- **`USER_AGENT` can no longer drift from the package version.** It was the literal `dsh-web-tavily/0.4.0` while the package shipped 0.4.1. It is now read from `package.json` at load time (through `createRequire(import.meta.url)`), with a graceful fallback to the bare plugin name when the manifest is unreadable — loading still never fails because of it.
|
|
11
|
+
- **`diag()` creates the log directory.** `~/.dsh-tui/dsh-web-tavily.log` was appended to without creating `~/.dsh-tui/`, so on a fresh machine every line was swallowed by the outer catch. The write path now creates the parent directory first; the "never throws" contract is unchanged.
|
|
12
|
+
- **Peer ranges widened to `^0.1.2-rc.1 || ^0.1.5-rc.1`.** `^0.1.2-rc.1` cannot match `0.1.5-rc.1`: semver lets a prerelease satisfy a range only when a comparator shares its `[major, minor, patch]` tuple, so every `0.1.x-rc.n` after `0.1.2` fell outside it. Today that is a warning rather than a failure (the profile template pins `autoInstallPeers: false`), but it would become an install error under strict peer enforcement. A future engine prerelease line needs its own clause.
|
|
13
|
+
|
|
14
|
+
### Documentation
|
|
15
|
+
|
|
16
|
+
- **The install steps now warn that saving `cordis.patch.yml` hot-reloads the running session.** A custom profile defaults to `patchReload: live`, so the edit takes effect immediately — not at the restart the README previously implied. If the `dsh-web-tavily` row has not been loaded yet, the `web` row points at a provider that is not registered and the session's web capability fails with `WEB_PROVIDER_CONFIGURED_MISSING` until the next restart. The safe order (install → `/restart` → edit the patch) is now spelled out.
|
|
17
|
+
- **Getting a Tavily API key is step 1**, with where the key goes (`~/.dsh/.credentials.yaml` under `refs:`, or the launching environment's `TAVILY_API_KEY`) and an explicit note not to commit it.
|
|
18
|
+
- The documented key-resolution order is corrected to match the code: literal `config.apiKey` first, then the credentials service, then the launching environment. The module header comment carried the same wrong order and is fixed too.
|
|
19
|
+
|
|
5
20
|
## 0.4.1 (2026-09-13)
|
|
6
21
|
|
|
7
22
|
- Documentation only, no code change. Installation now goes through `dsh plugin --profile dsh-tui add dsh-web-tavily` (the package is published) instead of copying files into `node_modules`, both READMEs gain a CI badge, and the release section records the OIDC trusted-publishing path.
|
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
**English** · [中文](README.zh.md)
|
|
6
6
|
|
|
7
|
+
Built for [dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI).
|
|
8
|
+
|
|
7
9
|
A host-plane Cordis plugin for dsh: it registers the **`tavily`** search provider
|
|
8
10
|
on dsh's web seam (`ctx.web`), so the `web_search` tool goes to the **Tavily
|
|
9
11
|
Search API** (`POST https://api.tavily.com/search`).
|
|
@@ -13,10 +15,10 @@ Search API** (`POST https://api.tavily.com/search`).
|
|
|
13
15
|
- DeepSeek's native search (`web-search-deepseek`) stays available as a fallback
|
|
14
16
|
you can switch to; set `web.searchProvider` back to `deepseek-official` (or
|
|
15
17
|
delete the key) to do so.
|
|
16
|
-
- The key is
|
|
17
|
-
credentials service (`refs:` in
|
|
18
|
-
|
|
19
|
-
provider never stores a key.
|
|
18
|
+
- The key is resolved per operation in this order: a literal `apiKey` in the
|
|
19
|
+
configuration first, then the credentials service (`refs:` in
|
|
20
|
+
`~/.dsh/.credentials.yaml`), then the launch environment. The reference
|
|
21
|
+
defaults to `TAVILY_API_KEY`, and the provider never stores a key.
|
|
20
22
|
|
|
21
23
|
## How it works
|
|
22
24
|
|
|
@@ -46,7 +48,14 @@ Search API** (`POST https://api.tavily.com/search`).
|
|
|
46
48
|
|
|
47
49
|
## Install
|
|
48
50
|
|
|
49
|
-
1.
|
|
51
|
+
1. **Get a Tavily account and an API key.** Register at <https://tavily.com/>,
|
|
52
|
+
create a key in the dashboard, and store it under `refs:` in
|
|
53
|
+
`~/.dsh/.credentials.yaml` — or export `TAVILY_API_KEY` in the environment
|
|
54
|
+
that launches dsh (see
|
|
55
|
+
[Where the key lives](#where-the-key-lives-local-only--never-in-a-repository)).
|
|
56
|
+
Never commit the key to a repository or paste it into a settings document.
|
|
57
|
+
|
|
58
|
+
2. Install it into your profile — it is published on npm as `dsh-web-tavily`:
|
|
50
59
|
|
|
51
60
|
```sh
|
|
52
61
|
dsh plugin --profile dsh-tui add dsh-web-tavily
|
|
@@ -54,7 +63,12 @@ Search API** (`POST https://api.tavily.com/search`).
|
|
|
54
63
|
# dsh plugin --profile dsh-tui add file:<path to this package>
|
|
55
64
|
```
|
|
56
65
|
|
|
57
|
-
|
|
66
|
+
3. **Restart dsh-tui before editing the patch** (`/restart`). Adding a plugin
|
|
67
|
+
only rewrites the profile's bundle list; it does **not** load the plugin into
|
|
68
|
+
the running session. Restarting here means the `tavily` provider is already
|
|
69
|
+
registered when the patch below is saved.
|
|
70
|
+
|
|
71
|
+
4. **Make tavily the default search backend.** This has to be written in the
|
|
58
72
|
profile's user patch layer (the `web:` section of `settings.yaml` does not
|
|
59
73
|
affect service configuration) — edit
|
|
60
74
|
`~/.dsh/profiles/dsh-tui/cordis.patch.yml` and add:
|
|
@@ -67,12 +81,21 @@ Search API** (`POST https://api.tavily.com/search`).
|
|
|
67
81
|
fetchProvider: http-trusted
|
|
68
82
|
```
|
|
69
83
|
|
|
84
|
+
⚠️ **Saving this file hot-reloads the running session — it is not
|
|
85
|
+
"restart to apply".** The profile's patch layer is watched, so the session is
|
|
86
|
+
reconfigured the instant the file is written. If the plugin is not loaded yet
|
|
87
|
+
(step 3 skipped), the `web` row immediately points at a provider that is not
|
|
88
|
+
registered, and `web_search` / web fetch fail in that session with
|
|
89
|
+
`WEB_PROVIDER_CONFIGURED_MISSING`. **A `/restart` recovers it**, because at
|
|
90
|
+
boot the plugin is registered and the patched row is read together. Editing
|
|
91
|
+
the patch first and restarting later is also safe for the boot — it just
|
|
92
|
+
leaves this session's web capability unavailable until that restart.
|
|
93
|
+
|
|
70
94
|
The `web` row belongs to the `dsh-base` layer, so **do not add a new row with
|
|
71
95
|
`insert:`** — the duplicate id crashes the boot with
|
|
72
96
|
`duplicate loader entry id: web`. Override the existing row by id instead, and
|
|
73
97
|
note that an override **replaces the whole config**, which is why
|
|
74
98
|
`fetchProvider` is restated above.
|
|
75
|
-
3. Restart dsh-tui (`/restart`).
|
|
76
99
|
|
|
77
100
|
## Configuration
|
|
78
101
|
|
|
@@ -106,6 +129,11 @@ refs:
|
|
|
106
129
|
TAVILY_API_KEY: 'tvly-...'
|
|
107
130
|
```
|
|
108
131
|
|
|
132
|
+
Exporting `TAVILY_API_KEY` in the environment that launches dsh works too — the
|
|
133
|
+
credentials store is consulted first, the launch environment second. A literal
|
|
134
|
+
key in `dsh-web-tavily.apiKey` is accepted as well and wins over both, but it
|
|
135
|
+
puts the secret in a settings document, so treat it as a last resort.
|
|
136
|
+
|
|
109
137
|
## Switching back to DeepSeek's native search
|
|
110
138
|
|
|
111
139
|
Set `web.searchProvider` to `deepseek-official` (or delete the key and let the
|
|
@@ -151,8 +179,10 @@ exchange for the complete safety preflight.
|
|
|
151
179
|
- `duplicate loader entry id: web` on boot — the profile's `cordis.patch.yml`
|
|
152
180
|
used `insert:` for a row that already exists; rewrite it as the by-id override
|
|
153
181
|
shown above.
|
|
154
|
-
- `web_search` answers `WEB_PROVIDER_CONFIGURED_MISSING` — the
|
|
155
|
-
|
|
182
|
+
- `web_search` answers `WEB_PROVIDER_CONFIGURED_MISSING` — the `web` row points
|
|
183
|
+
at a provider that is not registered: either the plugin did not load (check the
|
|
184
|
+
bundles list), or `cordis.patch.yml` was saved before the plugin was loaded,
|
|
185
|
+
which is a live reload (see [Install](#install)). `/restart` recovers it.
|
|
156
186
|
- `web_fetch` answers `WEB_BLOCKED_URL ... non-public IP` — the proxy fake-IP
|
|
157
187
|
preflight refused it: switch to `http-trusted`, or turn the proxy's fake-IP
|
|
158
188
|
mode off.
|
package/README.zh.md
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
**中文** · [English](README.md)
|
|
6
6
|
|
|
7
|
+
为 [dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI) 构建。
|
|
8
|
+
|
|
7
9
|
dsh host 平面 cordis 插件:为 dsh 的 web 能力 seam(`ctx.web`)注册搜索提供商 **`tavily`**,让 `web_search` 工具默认走 **Tavily Search API**(`POST https://api.tavily.com/search`)。
|
|
8
10
|
|
|
9
11
|
- 不替换 `web_search` 工具本身:工具、系统提示、展示卡片均保持原样,只有搜索后端换成 Tavily。
|
|
10
12
|
- 保留 DeepSeek 原生搜索(`web-search-deepseek`)为可切换备选;想切回只需把 `web.searchProvider` 改为 `deepseek-official` 或删掉该键。
|
|
11
|
-
- key
|
|
13
|
+
- key 按以下顺序解析:配置里的字面 `apiKey` 最优先,其次凭证服务
|
|
14
|
+
(`~/.dsh/.credentials.yaml` 的 `refs:`,引用名默认 `TAVILY_API_KEY`),最后是启动
|
|
15
|
+
环境变量。provider 不保留 key。
|
|
12
16
|
|
|
13
17
|
## 工作原理
|
|
14
18
|
|
|
@@ -32,7 +36,12 @@ dsh host 平面 cordis 插件:为 dsh 的 web 能力 seam(`ctx.web`)注册
|
|
|
32
36
|
|
|
33
37
|
## 安装
|
|
34
38
|
|
|
35
|
-
1.
|
|
39
|
+
1. **先注册 Tavily 账号并创建 API key。** 到 <https://tavily.com/> 注册,在控制台创建
|
|
40
|
+
key,然后放进 `~/.dsh/.credentials.yaml` 的 `refs:` 下,或在启动 dsh 的环境里导出
|
|
41
|
+
`TAVILY_API_KEY`(详见下文「key 存放」)。**不要把 key 提交进仓库,也不要写进设置
|
|
42
|
+
文档。**
|
|
43
|
+
|
|
44
|
+
2. 装进 profile —— 它以 `dsh-web-tavily` 发布在 npm 上:
|
|
36
45
|
|
|
37
46
|
```sh
|
|
38
47
|
dsh plugin --profile dsh-tui add dsh-web-tavily
|
|
@@ -40,7 +49,11 @@ dsh host 平面 cordis 插件:为 dsh 的 web 能力 seam(`ctx.web`)注册
|
|
|
40
49
|
# dsh plugin --profile dsh-tui add file:<本包路径>
|
|
41
50
|
```
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
3. **先 `/restart` 重启一次**,让插件行载入。`dsh plugin add` 只改写 profile 的 bundles
|
|
53
|
+
清单,**不会**把插件加载进运行中的会话;先重启,下一步保存补丁时 `tavily` provider
|
|
54
|
+
才已经注册好。
|
|
55
|
+
|
|
56
|
+
4. **把 web 服务默认搜索改为 tavily**(必须写在 profile 用户补丁层,`settings.yaml` 的 `web:` 段对服务配置无效)——
|
|
44
57
|
编辑 `~/.dsh/profiles/dsh-tui/cordis.patch.yml` 追加:
|
|
45
58
|
|
|
46
59
|
```yaml
|
|
@@ -51,10 +64,15 @@ dsh host 平面 cordis 插件:为 dsh 的 web 能力 seam(`ctx.web`)注册
|
|
|
51
64
|
fetchProvider: http-trusted
|
|
52
65
|
```
|
|
53
66
|
|
|
67
|
+
⚠️ **保存该文件会立即热重载运行中的会话,不是「重启后才生效」。** profile 补丁层被
|
|
68
|
+
文件监听器盯着,落盘那一刻当前会话就会被重新配置。若插件此时尚未加载(跳过了第 3
|
|
69
|
+
步),`web` 行立刻指向一个还没注册的 provider,当前会话的 `web_search`/联网能力当场报
|
|
70
|
+
`WEB_PROVIDER_CONFIGURED_MISSING`。**重启即恢复**:启动时插件与补丁一起读入。先改
|
|
71
|
+
补丁、稍后再重启对启动同样安全,只是当前会话的联网能力要等到那次重启才可用。
|
|
72
|
+
|
|
54
73
|
`web` 行由基座 dsh-base 提供,**不要用 `insert:` 新增同 id 行**——那会撞 id 直接崩
|
|
55
74
|
`duplicate loader entry id: web`;这里要按 id 覆盖既有行,且覆盖是**整行重写,需写全
|
|
56
75
|
`fetchProvider`**。
|
|
57
|
-
3. 重启 dsh-tui(`/restart`)生效。
|
|
58
76
|
|
|
59
77
|
## 配置
|
|
60
78
|
|
|
@@ -82,6 +100,10 @@ refs:
|
|
|
82
100
|
TAVILY_API_KEY: 'tvly-...'
|
|
83
101
|
```
|
|
84
102
|
|
|
103
|
+
也可以在启动 dsh 的环境里导出 `TAVILY_API_KEY`:解析时先查凭证服务、再查启动环境。
|
|
104
|
+
配置里的字面 `dsh-web-tavily.apiKey` 同样可用,且优先于以上两者,但它等于把密钥写进
|
|
105
|
+
设置文档,只建议作为最后手段。
|
|
106
|
+
|
|
85
107
|
## 切回 DeepSeek 原生搜索
|
|
86
108
|
|
|
87
109
|
把 `web.searchProvider` 改为 `deepseek-official`(或删除该键、让 seam 用唯一可用 provider)。注意 seam 不支持自动回退:Tavily 配置失效时搜索会明确报错,而**不会**悄悄走 DeepSeek。
|
|
@@ -106,7 +128,9 @@ config:
|
|
|
106
128
|
## 加载失败排查
|
|
107
129
|
|
|
108
130
|
- 插件启动报 `duplicate loader entry id: web`:profile `cordis.patch.yml` 误用 `insert:` 新增同 id 行,按上文改写为直接行。
|
|
109
|
-
- `web_search` 报 `WEB_PROVIDER_CONFIGURED_MISSING
|
|
131
|
+
- `web_search` 报 `WEB_PROVIDER_CONFIGURED_MISSING`:`web` 行指向的 provider 尚未注册
|
|
132
|
+
——要么插件没加载(检查 bundles 清单),要么 `cordis.patch.yml` 在插件加载前就被保存
|
|
133
|
+
(保存即热重载,见「安装」);`/restart` 即可恢复。
|
|
110
134
|
- `web_fetch` 报 `WEB_BLOCKED_URL ... non-public IP`:代理假 IP 预检拒绝,改用 `http-trusted` 或关闭代理 fake-IP 模式。
|
|
111
135
|
|
|
112
136
|
## 限制说明
|
package/dsh-plugin.json
CHANGED
package/lib/diag.js
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* `~/.dsh-tui/` capped at 128 KiB, and no file writes under `node --test`.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { appendFileSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { appendFileSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
15
15
|
import { homedir } from 'node:os';
|
|
16
|
-
import { join } from 'node:path';
|
|
16
|
+
import { dirname, join } from 'node:path';
|
|
17
17
|
|
|
18
18
|
/** Plugin-owned log path. */
|
|
19
19
|
export const DIAG_LOG = join(homedir(), '.dsh-tui', 'dsh-web-tavily.log');
|
|
@@ -31,6 +31,10 @@ function appendLogLine(path, line) {
|
|
|
31
31
|
catch {
|
|
32
32
|
// Missing or unreadable: the append below recreates it.
|
|
33
33
|
}
|
|
34
|
+
// A fresh machine has no ~/.dsh-tui/ yet; create it first, or the append
|
|
35
|
+
// throws and the caller's catch swallows the line — losing exactly the
|
|
36
|
+
// evidence this log exists to keep.
|
|
37
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
34
38
|
appendFileSync(path, line);
|
|
35
39
|
}
|
|
36
40
|
|
package/lib/index.js
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* capability seam (ctx.web). Registers the `tavily` provider so the
|
|
4
4
|
* model-facing web_search tool runs against the Tavily Search API
|
|
5
5
|
* (POST https://api.tavily.com/search). The provider holds no credential
|
|
6
|
-
* value: the key is resolved per operation
|
|
7
|
-
* (ref, default TAVILY_API_KEY), the
|
|
8
|
-
*
|
|
6
|
+
* value: the key is resolved per operation from a literal `apiKey` config
|
|
7
|
+
* first, then the credentials service (ref, default TAVILY_API_KEY), then the
|
|
8
|
+
* launch environment, in that order.
|
|
9
9
|
*
|
|
10
10
|
* The bundle additionally registers `http-trusted`, a proxy-friendly HTTP(S)
|
|
11
11
|
* fetch provider: it reuses the official @deepseek-ai/dsh-web-fetch-http
|
|
@@ -26,6 +26,7 @@ import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
|
|
|
26
26
|
import { WebError } from "@deepseek-ai/dsh-web";
|
|
27
27
|
import { HttpFetchProvider } from "@deepseek-ai/dsh-web-fetch-http";
|
|
28
28
|
import { lookup } from "node:dns/promises";
|
|
29
|
+
import { createRequire } from "node:module";
|
|
29
30
|
import { isIP } from "node:net";
|
|
30
31
|
import { diag } from "./diag.js";
|
|
31
32
|
import { applySettingsCard } from "./settings-card.js";
|
|
@@ -55,8 +56,24 @@ const DEFAULT_API_KEY_ENV = "TAVILY_API_KEY";
|
|
|
55
56
|
const BASE_URL_ENV = "TAVILY_BASE_URL";
|
|
56
57
|
/** Settings namespace carrying this provider's endpoint and behavior options. */
|
|
57
58
|
const SETTINGS_NAMESPACE = "dsh-web-tavily";
|
|
58
|
-
/**
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Build the attribution header from the installed manifest (`../package.json`,
|
|
61
|
+
* beside `lib/`). The version is read at load time so a release can never leave
|
|
62
|
+
* it stale; a missing/unreadable manifest or version degrades to the bare
|
|
63
|
+
* plugin name — attribution is never a reason a module fails to load.
|
|
64
|
+
*/
|
|
65
|
+
function userAgent() {
|
|
66
|
+
try {
|
|
67
|
+
const version = createRequire(import.meta.url)("../package.json").version;
|
|
68
|
+
if (typeof version === "string" && version.length > 0) return `${name}/${version}`;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Fall through to the name-only header.
|
|
72
|
+
}
|
|
73
|
+
return name;
|
|
74
|
+
}
|
|
75
|
+
/** Attribution header sent on every request. */
|
|
76
|
+
const USER_AGENT = userAgent();
|
|
60
77
|
/** Fallback result cap when the caller sends no maxResults. */
|
|
61
78
|
const DEFAULT_MAX_RESULTS = 10;
|
|
62
79
|
/** Tavily's documented per-request result cap. */
|
package/package.json
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-web-tavily",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Tavily-backed search provider for dsh: registers the `tavily` provider on ctx.web so the web_search tool runs against the Tavily Search API",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"dsh",
|
|
8
|
+
"dsh-plugin",
|
|
9
|
+
"dsh-tui",
|
|
10
|
+
"deepseek-harness",
|
|
11
|
+
"plugin",
|
|
12
|
+
"search",
|
|
13
|
+
"tavily",
|
|
14
|
+
"web-search"
|
|
15
|
+
],
|
|
6
16
|
"repository": {
|
|
7
17
|
"type": "git",
|
|
8
18
|
"url": "git+https://github.com/VviLliAm-qwq/dsh-web-tavily.git"
|
|
@@ -29,10 +39,13 @@
|
|
|
29
39
|
"peerDependencies": {
|
|
30
40
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
31
41
|
"@deepseek-ai/schemastery": "^3.18.2",
|
|
32
|
-
"@deepseek-ai/dsh-web": "^0.1.2-rc.1",
|
|
33
|
-
"@deepseek-ai/dsh-web-fetch-http": "^0.1.2-rc.1",
|
|
34
|
-
"@deepseek-ai/dsh-credentials": "^0.1.2-rc.1",
|
|
35
|
-
"@deepseek-ai/dsh-launch-environment": "^0.1.2-rc.1",
|
|
36
|
-
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1"
|
|
42
|
+
"@deepseek-ai/dsh-web": "^0.1.2-rc.1 || ^0.1.5-rc.1",
|
|
43
|
+
"@deepseek-ai/dsh-web-fetch-http": "^0.1.2-rc.1 || ^0.1.5-rc.1",
|
|
44
|
+
"@deepseek-ai/dsh-credentials": "^0.1.2-rc.1 || ^0.1.5-rc.1",
|
|
45
|
+
"@deepseek-ai/dsh-launch-environment": "^0.1.2-rc.1 || ^0.1.5-rc.1",
|
|
46
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1 || ^0.1.5-rc.1"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"ipaddr.js": "^2.5.0"
|
|
37
50
|
}
|
|
38
51
|
}
|