dsh-pocket 1.4.7 → 1.5.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/README.en.md +5 -0
- package/README.md +5 -0
- package/lib/index.js +2 -0
- package/lib/service.mjs +38 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://www.npmjs.com/package/dsh-pocket"><img alt="npm" src="https://img.shields.io/npm/v/dsh-pocket?color=4d6bfe&label=npm"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/dsh-pocket"><img alt="downloads" src="https://img.shields.io/npm/dm/dsh-pocket?color=4d6bfe"></a>
|
|
11
12
|
<a href="https://github.com/shaobeichen/dsh-pocket/actions"><img alt="CI" src="https://github.com/shaobeichen/dsh-pocket/actions/workflows/npm-publish.yml/badge.svg"></a>
|
|
12
13
|
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-GPL--2.0-red.svg"></a>
|
|
13
14
|
<a href="https://github.com/shaobeichen/dsh-pocket/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/shaobeichen/dsh-pocket"></a>
|
|
@@ -16,6 +17,10 @@
|
|
|
16
17
|
|
|
17
18
|
> Put **DeepSeek Harness in your pocket**: one package, one settings tab — scan a QR code and your phone shows exactly what's on your computer screen, live, from anywhere.
|
|
18
19
|
|
|
20
|
+
<p align="center">
|
|
21
|
+
⭐ A Star would make the author's day · <a href="https://github.com/shaobeichen/dsh-pocket">Here, take one</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
19
24
|
## What is this
|
|
20
25
|
|
|
21
26
|
**You want to use DeepSeek Harness on your computer, even when you're not at the computer.**
|
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://www.npmjs.com/package/dsh-pocket"><img alt="npm" src="https://img.shields.io/npm/v/dsh-pocket?color=4d6bfe&label=npm"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/dsh-pocket"><img alt="downloads" src="https://img.shields.io/npm/dm/dsh-pocket?color=4d6bfe"></a>
|
|
11
12
|
<a href="https://github.com/shaobeichen/dsh-pocket/actions"><img alt="CI" src="https://github.com/shaobeichen/dsh-pocket/actions/workflows/npm-publish.yml/badge.svg"></a>
|
|
12
13
|
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-GPL--2.0-red.svg"></a>
|
|
13
14
|
<a href="https://github.com/shaobeichen/dsh-pocket/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/shaobeichen/dsh-pocket"></a>
|
|
@@ -16,6 +17,10 @@
|
|
|
16
17
|
|
|
17
18
|
> 把 **DeepSeek Harness 装进你的口袋**:一个包、一个设置页,手机扫二维码就实时看到电脑上的同一个界面——人在外面也能用。
|
|
18
19
|
|
|
20
|
+
<p align="center">
|
|
21
|
+
⭐ 顺手留颗 Star,作者能高兴一整天 · <a href="https://github.com/shaobeichen/dsh-pocket">行,给你一颗 Star</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
19
24
|
## 这是什么
|
|
20
25
|
|
|
21
26
|
**你不在电脑前,也想用电脑上的 DeepSeek Harness。**
|
package/lib/index.js
CHANGED
|
@@ -148,6 +148,8 @@ export function apply(ctx, config = {}, internals = {}) {
|
|
|
148
148
|
// 代理随插件自动启动(局域网二维码开箱即用,零配置)
|
|
149
149
|
void service.startProxy().then((proxy) => {
|
|
150
150
|
logger.info('dsh-pocket: proxy ready on :%d | 局域网代理已就绪', proxy.port);
|
|
151
|
+
// 自动恢复上次开启的公网隧道(DSH 重启后 cloudflared 子进程被杀,issue #11)
|
|
152
|
+
void service.restoreTunnelIfNeeded?.().catch(() => {});
|
|
151
153
|
}).catch((err) => {
|
|
152
154
|
logger.error('dsh-pocket: proxy start failed | 代理启动失败: %s', err?.message ?? err);
|
|
153
155
|
});
|
package/lib/service.mjs
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
import { networkInterfaces } from 'node:os';
|
|
10
10
|
import { createRequire } from 'node:module';
|
|
11
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { join, dirname } from 'node:path';
|
|
11
13
|
import { createPocketProxy } from './proxy.mjs';
|
|
12
14
|
import { startQuickTunnel } from './tunnel.mjs';
|
|
13
15
|
|
|
@@ -112,6 +114,21 @@ export function createPocketService({
|
|
|
112
114
|
return qrCache.get(text);
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
// 公网隧道自动恢复(issue #11):DSH 重启后 cloudflared 子进程被杀、隧道消失,
|
|
118
|
+
// 插件无从知晓。启动时检查持久化的「隧道开启中」标记,自动重新拉起。
|
|
119
|
+
const autoStatePath = home ? join(home, 'dsh-pocket', 'tunnel-auto.json') : null;
|
|
120
|
+
async function persistAutoTunnel() {
|
|
121
|
+
if (!autoStatePath) return;
|
|
122
|
+
try {
|
|
123
|
+
await mkdir(dirname(autoStatePath), { recursive: true });
|
|
124
|
+
await writeFile(autoStatePath, JSON.stringify({ at: Date.now() }), 'utf8');
|
|
125
|
+
} catch { /* 忽略 */ }
|
|
126
|
+
}
|
|
127
|
+
async function clearAutoTunnel() {
|
|
128
|
+
if (!autoStatePath) return;
|
|
129
|
+
try { await rm(autoStatePath, { force: true }); } catch { /* 忽略 */ }
|
|
130
|
+
}
|
|
131
|
+
|
|
115
132
|
return {
|
|
116
133
|
dshPort,
|
|
117
134
|
/** 启动局域网代理(幂等)。端口被占(EADDRINUSE,如桌面版与普通环境同时运行)时自动尝试下一个端口。 */
|
|
@@ -166,6 +183,8 @@ export function createPocketService({
|
|
|
166
183
|
tunnelState.phase = 'error';
|
|
167
184
|
tunnelState.detail = `隧道进程退出(code=${code})| tunnel process exited`;
|
|
168
185
|
});
|
|
186
|
+
// 记录「隧道开启中」,供重启后自动恢复(issue #11)
|
|
187
|
+
void persistAutoTunnel();
|
|
169
188
|
return tunnel.url;
|
|
170
189
|
} catch (err) {
|
|
171
190
|
// stopTunnel 触发的 abort 不算错误:保持 idle,别把状态刷成 error
|
|
@@ -195,6 +214,25 @@ export function createPocketService({
|
|
|
195
214
|
tunnelState.phase = 'idle';
|
|
196
215
|
tunnelState.detail = '';
|
|
197
216
|
tunnelState.startedAt = null;
|
|
217
|
+
void clearAutoTunnel(); // 手动关闭后不再自动恢复
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
/** 启动时自动恢复上次开启的公网隧道(DSH 重启后 cloudflared 子进程被杀,issue #11)。 */
|
|
221
|
+
async restoreTunnelIfNeeded() {
|
|
222
|
+
if (!autoStatePath || tunnel || tunnelPromise) return;
|
|
223
|
+
let has = false;
|
|
224
|
+
try {
|
|
225
|
+
const raw = await readFile(autoStatePath, 'utf8');
|
|
226
|
+
has = /"at"\s*:/.test(raw);
|
|
227
|
+
} catch { return; } // 无标记 → 不恢复
|
|
228
|
+
if (!has) return;
|
|
229
|
+
try {
|
|
230
|
+
await this.startTunnel();
|
|
231
|
+
console.log('dsh-pocket: public tunnel auto-restored | 已自动恢复公网隧道');
|
|
232
|
+
} catch (err) {
|
|
233
|
+
// 恢复失败保留标记(下次启动再试);网络问题见 README 排障
|
|
234
|
+
console.warn('dsh-pocket: tunnel auto-restore failed | 自动恢复隧道失败: %s', err?.message ?? err);
|
|
235
|
+
}
|
|
198
236
|
},
|
|
199
237
|
|
|
200
238
|
/** 状态快照(RPC 返回,不含敏感信息;二维码 data URL 本地生成 + 缓存)。 */
|
package/package.json
CHANGED