dsh-voice-mode 0.7.20 → 0.7.22
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/README.en.md +19 -1
- package/README.md +19 -1
- package/lib/client.js +4 -2
- package/lib/index.js +14 -2
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -16,7 +16,7 @@ interrupts playback and the running turn. No API key.
|
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
|
|
19
|
-
> **Runtime changes (most recent batch: v0.7.17 – v0.7.19, 2026-10-02)**: (1) **Settings work on every dsh version** — fixed the settings page and persistence on dsh 0.1.7+ (dedicated Settings → Voice Mode page, writes survive restarts); (2) **i18n reworked** — the UI follows dsh's official language setting, Chinese/English are fully consistent and switch without a reload; (3) **fixed fresh-install failures with npm/pnpm and `failed to import` on dsh ≥0.1.7** (affects 0.7.17 and earlier — please upgrade to ≥0.7.18); (4) **local Kokoro fixed on the official Electron desktop host** — needs Node.js ≥18 on PATH (see the desktop note below). Earlier batches (v0.7.10: silent-audio fixes, etc.) and the full history are in [`CHANGELOG.md`](
|
|
19
|
+
> **Runtime changes (most recent batch: v0.7.17 – v0.7.19, 2026-10-02)**: (1) **Settings work on every dsh version** — fixed the settings page and persistence on dsh 0.1.7+ (dedicated Settings → Voice Mode page, writes survive restarts); (2) **i18n reworked** — the UI follows dsh's official language setting, Chinese/English are fully consistent and switch without a reload; (3) **fixed fresh-install failures with npm/pnpm and `failed to import` on dsh ≥0.1.7** (affects 0.7.17 and earlier — please upgrade to ≥0.7.18); (4) **local Kokoro fixed on the official Electron desktop host** — needs Node.js ≥18 on PATH (see the desktop note below). Earlier batches (v0.7.10: silent-audio fixes, etc.) and the full history are in [`CHANGELOG.md`](https://github.com/qishuilalala/dsh-voice-mode/blob/main/CHANGELOG.md).
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -303,6 +303,23 @@ flowchart LR
|
|
|
303
303
|
|
|
304
304
|
---
|
|
305
305
|
|
|
306
|
+
## 🔐 Permissions and data flow
|
|
307
|
+
|
|
308
|
+
An honest disclosure of what the plugin does (mapped to the awesome-dsh-plugin capability scan: `network / fs-read / fs-write / shell / env`):
|
|
309
|
+
|
|
310
|
+
| Category | What it does | Where data goes |
|
|
311
|
+
| --- | --- | --- |
|
|
312
|
+
| **network** | (1) The default read-aloud engine **Edge** sends the **reply text to be spoken** over WebSocket to Microsoft `speech.platform.bing.com` (cloud synthesis — switch to local VITS / Kokoro to stay fully offline); (2) downloads local models on first use from `huggingface.co` (or your configured mirror `hf-mirror.com`) with a host allowlist and pinned SHA256; (3) registers loopback HTTP routes `/voice-mode/*` on the dsh host (loopback only by default; LAN needs `allowLan`) | Microphone audio **never leaves your machine** (recognition runs locally via sherpa-onnx); only reply text goes to Microsoft, and only with the Edge engine |
|
|
313
|
+
| **fs-read / fs-write** | Model cache (Linux/macOS `~/.cache/dsh-voice-mode/models/`, Windows `%LOCALAPPDATA%\dsh-voice-mode\models\`); the dsh 0.1.7+ settings overlay `$DSH_HOME/voice-mode.settings.json`; **never touches your workspace files** | All local |
|
|
314
|
+
| **shell (child processes)** | Local TTS synthesis runs in a separate child process (`child_process.fork` → `lib/tts-vits-worker.cjs`); when the host is Electron (the official desktop app), it additionally probes and launches a real Node.js for Kokoro (`node -p …` to check the version). **It never executes user input and never builds shell command strings** | Local |
|
|
315
|
+
| **env** | Reads only `DSH_HOME`, `LOCALAPPDATA` (for directories) and the optional `DSHVM_NODE`; **no API key is read or needed** | — |
|
|
316
|
+
|
|
317
|
+
Also: the on-device recording fixture used for debugging is **off by default**; the plugin sends no telemetry. See [`SECURITY.md`](https://github.com/qishuilalala/dsh-voice-mode/blob/main/SECURITY.md) for the threat model and how to report vulnerabilities.
|
|
318
|
+
|
|
319
|
+
### Compatibility declaration (what the plugin market's version filter reads)
|
|
320
|
+
|
|
321
|
+
`package.json` declares `engines.dsh = ">=0.1.1-rc.2"` (the market uses it for "filter by host version"). Verified range: **0.1.1-rc.2 → 0.2.1-alpha.1** (including an Electron host equivalent to the official desktop app). The upper bound is open; a weekly CI check watches upstream releases and opens an issue for any uncovered version. `peerDependencies` only lists `@deepseek-ai/cordis` and `react` (provided by the host).
|
|
322
|
+
|
|
306
323
|
## 🚧 Known limitations
|
|
307
324
|
|
|
308
325
|
- Barge-in relies on browser echo cancellation (`echoCancellation`); loud speaker volume may leak into the mic (no JS-level AEC)
|
|
@@ -323,6 +340,7 @@ flowchart LR
|
|
|
323
340
|
| Mic click does nothing, red hint in the status bar | The browser denied mic permission: allow it in the address bar and retry |
|
|
324
341
|
| Status bar stuck on `Loading model… x%` | Check the network; the model is large (160 MB) — `npm run prefetch` first; on mainland networks set `modelHost` to `https://hf-mirror.com` |
|
|
325
342
|
| Status bar shows `Model download failed (<file>)` | Both mirrors are unreachable: check network/proxy and re-enter voice mode (resumable) |
|
|
343
|
+
| Local Kokoro on the official desktop app shows "failed" and asks for Node.js | The desktop host is Electron, where Kokoro's native add-on cannot run: install Node.js >= 18 on PATH (or set `DSHVM_NODE` to its path) and retry, or use the default Edge / local VITS (unaffected on desktop) |
|
|
326
344
|
| Caption appears (overlay) but no sound | Check system volume/output; if autoplay is blocked, click anywhere on the page and retry |
|
|
327
345
|
| Status bar shows `朗读连接失败:正在重试…` | Edge TTS unreachable (overseas service), auto-retries; if it persists, check network/proxy |
|
|
328
346
|
| Poor recognition | Get closer to the mic, reduce ambient noise; if echo remains, raise the interrupt sensitivity by one step |
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ DeepSeek Harness 语音双工对话模式:会话内一键进入 → 边说边
|
|
|
17
17
|
|
|
18
18
|

|
|
19
19
|
|
|
20
|
-
> **运行时变更(最近一批:v0.7.17 ~ v0.7.19,2026-10-02)**:① **设置面全版本打通**——dsh 0.1.7+ 上设置页与持久化修复(Settings → 语音模式 专属页、写入与重启保留);② **国际化重做**——界面语言跟随 dsh 官方语言设置,中/英文完整一致、切换无需刷新;③ **修复 npm/pnpm 全新安装失败与 dsh ≥0.1.7 已安装形态「failed to import」**(0.7.17 及更早版本受影响,请升级到 ≥0.7.18);④ **官方桌面端(Electron)下本地 Kokoro 修复**——需系统 PATH 上有 Node.js ≥18(见下文「桌面端提示」)。此前批次(v0.7.10:输出链路静默丢音根治等)与完整历史见 [`CHANGELOG.md`](
|
|
20
|
+
> **运行时变更(最近一批:v0.7.17 ~ v0.7.19,2026-10-02)**:① **设置面全版本打通**——dsh 0.1.7+ 上设置页与持久化修复(Settings → 语音模式 专属页、写入与重启保留);② **国际化重做**——界面语言跟随 dsh 官方语言设置,中/英文完整一致、切换无需刷新;③ **修复 npm/pnpm 全新安装失败与 dsh ≥0.1.7 已安装形态「failed to import」**(0.7.17 及更早版本受影响,请升级到 ≥0.7.18);④ **官方桌面端(Electron)下本地 Kokoro 修复**——需系统 PATH 上有 Node.js ≥18(见下文「桌面端提示」)。此前批次(v0.7.10:输出链路静默丢音根治等)与完整历史见 [`CHANGELOG.md`](https://github.com/qishuilalala/dsh-voice-mode/blob/main/CHANGELOG.md)。
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
@@ -262,6 +262,23 @@ flowchart LR
|
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
|
265
|
+
## 🔐 权限与数据流声明
|
|
266
|
+
|
|
267
|
+
插件如实声明它会做的事(与 awesome-dsh-plugin 的能力扫描 `network / fs-read / fs-write / shell / env` 一一对应):
|
|
268
|
+
|
|
269
|
+
| 类别 | 具体行为 | 数据去向 |
|
|
270
|
+
| --- | --- | --- |
|
|
271
|
+
| **network** | ① 默认朗读引擎 **Edge**:把**待朗读的回复文本**经 WebSocket 发给微软 `speech.platform.bing.com`(云端合成;想完全离线请切到本地 VITS / Kokoro);② 首次使用本地模型时从 `huggingface.co`(或你配置的镜像 `hf-mirror.com`)下载,主机白名单 + 固定 SHA256 校验;③ 在 dsh 宿主上注册回环 HTTP 路由 `/voice-mode/*`(默认仅回环,需 `allowLan` 才对局域网开放) | 麦克风音频**不出本机**(识别在本地 sherpa-onnx);仅回复文本在 Edge 引擎下发往微软 |
|
|
272
|
+
| **fs-read / fs-write** | 模型缓存(Linux/macOS `~/.cache/dsh-voice-mode/models/`,Windows `%LOCALAPPDATA%\dsh-voice-mode\models\`);dsh 0.1.7+ 的设置覆盖层 `$DSH_HOME/voice-mode.settings.json`;**不读写你的工作区文件** | 全部在本机 |
|
|
273
|
+
| **shell(子进程)** | 本地 TTS 合成跑在独立子进程(`child_process.fork` → `lib/tts-vits-worker.cjs`);宿主为 Electron(官方桌面端)时,为 Kokoro 额外探测并启动一个真正的 Node.js(`node -p …` 探测版本,见 ADR/兼容契约)。**不执行用户输入、不经 shell 拼接命令** | 本机 |
|
|
274
|
+
| **env** | 仅读取 `DSH_HOME`、`LOCALAPPDATA`(取目录)与可选的 `DSHVM_NODE`;**不读取、不需要任何 API Key** | — |
|
|
275
|
+
|
|
276
|
+
补充:调试用的真机录制(fixture)默认**关闭**;插件不上传遥测。完整威胁模型与漏洞报告方式见仓库根目录 [`SECURITY.md`](https://github.com/qishuilalala/dsh-voice-mode/blob/main/SECURITY.md)。
|
|
277
|
+
|
|
278
|
+
### 兼容声明(插件市场的版本筛选依据)
|
|
279
|
+
|
|
280
|
+
`package.json` 声明 `engines.dsh = ">=0.1.1-rc.2"`(插件市场据此在「按宿主版本筛选」时判定兼容)。已实测范围 **0.1.1-rc.2 → 0.2.1-alpha.1**(含官方桌面端等价的 Electron 宿主);上限开放,由每周 CI 巡检上游新版本并复验,出现未覆盖版本会自动开 issue。`peerDependencies` 仅声明 `@deepseek-ai/cordis` 与 `react`(宿主提供)。
|
|
281
|
+
|
|
265
282
|
## 🚧 已知限制
|
|
266
283
|
|
|
267
284
|
- 发声打断依赖浏览器回声消除(`echoCancellation`);扬声器音量过大时可能漏声到麦克风
|
|
@@ -296,6 +313,7 @@ flowchart LR
|
|
|
296
313
|
| 唤醒词完全没反应 | ① 确认交互模式是 `toggle`(`hold` 与手动打断下唤醒词不生效);② 确认 `bargeInMode`:`manual`(或 `detect` 在本机无原生回声消除时自动落 manual)会关闭常驻聆听 → 唤醒词失效,改回 `auto` 或按住麦克风/Ctrl;③ 朗读期说唤醒词不触发(先等 AI 说完);④ 看待机态实时转写,确认它听到了什么(同音字 1 字内已容错,建议 3-4 字词) |
|
|
297
314
|
| 按住说话松手后没反应 | 确认交互模式为「按住说」且按住期间按钮高亮;松手后识别定稿约 1 秒内进入草稿 |
|
|
298
315
|
| 打不断(朗读中开口无反应) | 调高 `interruptLevel`(更敏感档 = 0 或 1)或检查麦克风权限;若 VAD 持续不触发可临时切到「手动打断」(`mode: hold` / 唤醒词定时延后);**不要**调 `echoGateDb`——真机 3.1 分钟朗读期里 Silero 0/777 帧把回声判成语音,原生 AEC 生效时此阈值从未被执行(详见 ADR-0006) |
|
|
316
|
+
| 官方桌面端上选本地 Kokoro,设置里显示「加载失败」并提示需要 Node.js | 桌面端宿主是 Electron,Kokoro 的原生 addon 在其中不可用:在系统 PATH 上安装 Node.js ≥18(或设环境变量 `DSHVM_NODE` 指向它)后重试;或改用默认的 Edge / 本地 VITS(桌面端不受影响) |
|
|
299
317
|
| 字幕被输入框挡住 | 默认 `captionMaxWidth=1`(70vw)+ `captionFontSize=0`(12px)在窄屏可能与底部输入框重叠;调高档位或点字幕浮层「×」收起 |
|
|
300
318
|
| 让位行为异常(朗读期说「嗯」不停 / 真话被打断) | 「嗯/对」类短词触发让位 1.5s 后继续朗读;继续说真话会走硬打断;不要时关 `backchannelYield` 即可恢复改造前行为(ADR-0008) |
|
|
301
319
|
| 朗读期说「嗯」没让位 | 确认 `backchannelYield=true`(默认开);hold 模式松手后让位 1.5s 内继续说话会变硬打断 |
|
package/lib/client.js
CHANGED
|
@@ -1534,6 +1534,7 @@ var zh = {
|
|
|
1534
1534
|
engineLoading: "\u52A0\u8F7D\u4E2D\u2026",
|
|
1535
1535
|
engineReady: "\u5C31\u7EEA",
|
|
1536
1536
|
engineError: "\u52A0\u8F7D\u5931\u8D25",
|
|
1537
|
+
errKokoroNeedsNode: "\u672C\u5730 Kokoro \u65E0\u6CD5\u5728\u5B98\u65B9\u684C\u9762\u7AEF\uFF08Electron\uFF09\u5185\u76F4\u63A5\u8FD0\u884C\uFF1A\u8BF7\u5728\u7CFB\u7EDF PATH \u4E0A\u5B89\u88C5 Node.js \u226518\uFF08\u6216\u8BBE\u73AF\u5883\u53D8\u91CF DSHVM_NODE \u6307\u5411\u5B83\uFF09\uFF0C\u6216\u628A\u6717\u8BFB\u5F15\u64CE\u5207\u6362\u4E3A Edge / \u672C\u5730 VITS\u3002",
|
|
1537
1538
|
ttsModelsMissing: "\u672C\u5730\u6A21\u578B\u672A\u5C31\u7EEA",
|
|
1538
1539
|
ttsDownload: "\u4E0B\u8F7D",
|
|
1539
1540
|
ttsDelete: "\u5220\u9664",
|
|
@@ -1763,6 +1764,7 @@ var en = {
|
|
|
1763
1764
|
engineLoading: "loading\u2026",
|
|
1764
1765
|
engineReady: "ready",
|
|
1765
1766
|
engineError: "failed",
|
|
1767
|
+
errKokoroNeedsNode: "Local Kokoro cannot run directly inside the official desktop app (Electron): install Node.js >= 18 on PATH (or set DSHVM_NODE to its path), or switch the read-aloud engine to Edge / local VITS.",
|
|
1766
1768
|
ttsModelsMissing: "local models missing",
|
|
1767
1769
|
ttsDownload: "Download",
|
|
1768
1770
|
ttsDelete: "Delete",
|
|
@@ -2749,7 +2751,7 @@ function EngineStatusInline() {
|
|
|
2749
2751
|
children: acting ? acting === "clean" ? t("ttsDeleting") : t("ttsDownloading") : action === "clean" ? t("ttsDelete") : t("ttsDownload")
|
|
2750
2752
|
}
|
|
2751
2753
|
),
|
|
2752
|
-
tts.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, color: "var(--dsw-alias-state-error-primary)", flexBasis: "100%" }, children: tts.error })
|
|
2754
|
+
tts.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 11, color: "var(--dsw-alias-state-error-primary)", flexBasis: "100%" }, children: tts.errorCode === "kokoro_needs_node" ? t("errKokoroNeedsNode") : tts.error })
|
|
2753
2755
|
] });
|
|
2754
2756
|
}
|
|
2755
2757
|
function ModelStatusView() {
|
|
@@ -3099,7 +3101,7 @@ var TELEMETRY_VIEW = [
|
|
|
3099
3101
|
{ stage: "first-tts-chunk", key: "telFirstChunk" },
|
|
3100
3102
|
{ stage: "first-audio-played", key: "telFirstPlayed" }
|
|
3101
3103
|
];
|
|
3102
|
-
var BUILD_TAG = "
|
|
3104
|
+
var BUILD_TAG = "b05db39";
|
|
3103
3105
|
var TELEMETRY_FLAG = "dsh-voice-mode.telemetry";
|
|
3104
3106
|
var telemetryEnabled = typeof localStorage !== "undefined" && localStorage.getItem(TELEMETRY_FLAG) === "1";
|
|
3105
3107
|
console.log("[dsh-voice] build=" + BUILD_TAG);
|
package/lib/index.js
CHANGED
|
@@ -1313,6 +1313,13 @@ var probeNode = (command, env) => {
|
|
|
1313
1313
|
}
|
|
1314
1314
|
};
|
|
1315
1315
|
var NATIVE_RUNTIME_UNAVAILABLE = 'Local Kokoro cannot run inside the Electron-based desktop host (native add-on blocked: "External buffers are not allowed"). Install Node.js >= 18 on PATH (or set DSHVM_NODE to its path), or switch the read-aloud engine to Edge or VITS.';
|
|
1316
|
+
var NativeRuntimeUnavailableError = class extends Error {
|
|
1317
|
+
code = "kokoro_needs_node";
|
|
1318
|
+
constructor() {
|
|
1319
|
+
super(NATIVE_RUNTIME_UNAVAILABLE);
|
|
1320
|
+
this.name = "NativeRuntimeUnavailableError";
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1316
1323
|
var cached;
|
|
1317
1324
|
function resolveNativeRuntime(opts = {}) {
|
|
1318
1325
|
const env = opts.env ?? process.env;
|
|
@@ -1660,6 +1667,7 @@ function createSherpaLocalEngine(options) {
|
|
|
1660
1667
|
let ready = null;
|
|
1661
1668
|
let engineLoading = false;
|
|
1662
1669
|
let engineError;
|
|
1670
|
+
let engineErrorCode;
|
|
1663
1671
|
let nextId = 1;
|
|
1664
1672
|
const pending = /* @__PURE__ */ new Map();
|
|
1665
1673
|
const call = (msg) => new Promise((resolve, reject) => {
|
|
@@ -1681,6 +1689,7 @@ function createSherpaLocalEngine(options) {
|
|
|
1681
1689
|
ready = (async () => {
|
|
1682
1690
|
engineLoading = true;
|
|
1683
1691
|
engineError = void 0;
|
|
1692
|
+
engineErrorCode = void 0;
|
|
1684
1693
|
downloadProgress = null;
|
|
1685
1694
|
try {
|
|
1686
1695
|
if (!child || !childInit) {
|
|
@@ -1708,7 +1717,7 @@ function createSherpaLocalEngine(options) {
|
|
|
1708
1717
|
}
|
|
1709
1718
|
if (!child) {
|
|
1710
1719
|
const runtime = options.kind === "kokoro" ? resolveNativeRuntime() : { env: process.env };
|
|
1711
|
-
if (!runtime) throw new
|
|
1720
|
+
if (!runtime) throw new NativeRuntimeUnavailableError();
|
|
1712
1721
|
child = fork(workerPath, [], {
|
|
1713
1722
|
stdio: ["ignore", "ignore", "pipe", "ipc"],
|
|
1714
1723
|
...runtime.execPath ? { execPath: runtime.execPath, env: runtime.env } : {}
|
|
@@ -1754,6 +1763,7 @@ function createSherpaLocalEngine(options) {
|
|
|
1754
1763
|
broadcast("tts-ready", { engine: options.kind, worker: true });
|
|
1755
1764
|
} catch (e) {
|
|
1756
1765
|
engineError = e instanceof Error ? e.message : String(e);
|
|
1766
|
+
engineErrorCode = e instanceof NativeRuntimeUnavailableError ? e.code : void 0;
|
|
1757
1767
|
throw e;
|
|
1758
1768
|
} finally {
|
|
1759
1769
|
engineLoading = false;
|
|
@@ -1790,6 +1800,7 @@ function createSherpaLocalEngine(options) {
|
|
|
1790
1800
|
ready: childInit === true,
|
|
1791
1801
|
loading: engineLoading,
|
|
1792
1802
|
error: engineError,
|
|
1803
|
+
errorCode: engineErrorCode,
|
|
1793
1804
|
progress: downloadProgress ?? void 0,
|
|
1794
1805
|
local: {
|
|
1795
1806
|
repo: repoName,
|
|
@@ -2064,6 +2075,7 @@ var en = {
|
|
|
2064
2075
|
engineLoading: "loading\u2026",
|
|
2065
2076
|
engineReady: "ready",
|
|
2066
2077
|
engineError: "failed",
|
|
2078
|
+
errKokoroNeedsNode: "Local Kokoro cannot run directly inside the official desktop app (Electron): install Node.js >= 18 on PATH (or set DSHVM_NODE to its path), or switch the read-aloud engine to Edge / local VITS.",
|
|
2067
2079
|
ttsModelsMissing: "local models missing",
|
|
2068
2080
|
ttsDownload: "Download",
|
|
2069
2081
|
ttsDelete: "Delete",
|
|
@@ -2284,7 +2296,7 @@ var name = "voice-mode";
|
|
|
2284
2296
|
var NS_VOICE_MODE = "voice-mode";
|
|
2285
2297
|
var BASE_PATH = "/voice-mode";
|
|
2286
2298
|
var PREVIEW_NETWORK_PATTERN = /fetch failed|ECONN|ENOTFOUND|getaddrinfo|ETIMEDOUT|EAI_AGAIN|network|unreachable|socket hang up|aborted/i;
|
|
2287
|
-
var PREVIEW_ENGINE_PATTERN = /model download|model verify|init failed|child exited|tts child|local TTS|prepare|sherpa/i;
|
|
2299
|
+
var PREVIEW_ENGINE_PATTERN = /model download|model verify|init failed|child exited|tts child|local TTS|prepare|sherpa|local Kokoro/i;
|
|
2288
2300
|
var PREVIEW_TEXT_PATTERN = /empty or invalid audio|invalid audio|invalid text|too long|truncat/i;
|
|
2289
2301
|
function classifyPreviewError(msg) {
|
|
2290
2302
|
if (PREVIEW_TEXT_PATTERN.test(msg)) return "text";
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-voice-mode",
|
|
3
3
|
"description": "Full-duplex voice plugin for DeepSeek Harness: local zipformer2 streaming ASR (no API key) → editable draft; Edge TTS or local VITS / Kokoro read-aloud with live captions; true barge-in; hardened HTTP surface + model SHA256 pinning; compatible with all dsh releases since 0.1.1-rc.2 (verified 0.1.1-rc.2 → 0.2.0-rc.2).",
|
|
4
4
|
"icon": "./icon.svg",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.22",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|
|
8
8
|
"repository": {
|