@mrrisega/dsh-remote 0.4.8 → 0.4.9

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.md CHANGED
@@ -63,12 +63,9 @@ dsh-remote 是一个轻量的**隧道模式**远程控制方案:电脑端运
63
63
  npx @mrrisega/dsh-remote
64
64
  ```
65
65
 
66
- 安装完成后运行下面命令打开设置页,用手机号+密码登录即可(注册在手机端完成,
67
- 登录后 bridge 自动启动):
68
-
69
- ```bash
70
- npx @mrrisega/dsh-remote settings
71
- ```
66
+ 安装完成后**无需任何命令**:打开 dsh web → 设置 → 「远程控制」,注册/登录手机号即可
67
+ (注册在手机端完成,登录后 bridge 自动启动;自建用户在同一面板切「自建服务」标签)。
68
+ 原来的独立设置页(`dsh-remote settings`)已移除,避免与插件面板重复造成困惑。
72
69
 
73
70
  自建模式(自己部署了 relay-router,无需账号体系):
74
71
 
@@ -76,7 +73,7 @@ npx @mrrisega/dsh-remote settings
76
73
  npx @mrrisega/dsh-remote setup --server wss://<你的域名>:端口 --key <访问密钥>
77
74
  ```
78
75
 
79
- 其他命令:`settings`(设置页)、`status`(查看状态)、`run`(前台调试)、
76
+ 其他命令:`status`(查看状态)、`run`(前台调试)、`settings`(仅显示登录指引)、
80
77
  `plugin`(重装/卸载 dsh web 插件)。运行 `npx @mrrisega/dsh-remote --help` 查看完整说明。
81
78
 
82
79
  > **版本与更新 / 卸载**:dsh 官方插件市场目前不提供更新按钮,也不会改写用户补丁(因此市场
package/dsh-setup.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * 用法:
6
6
  * dsh-remote [setup] [选项] 一键安装(默认命令,无需任何参数)
7
- * dsh-remote settings 打开本地设置页(登录账号 / 自建配置)
7
+ * dsh-remote settings 提示如何登录(独立设置页已移除,见 dsh web 面板)
8
8
  * dsh-remote run 前台运行 bridge(调试/守护)
9
9
  * dsh-remote status 查看配置与服务状态
10
10
  * dsh-remote plugin [--uninstall] 手动安装/卸载 dsh web 远程控制插件
@@ -19,10 +19,10 @@
19
19
  * 1. 写入配置 <CONFIG_DIR>/.dsh-config.json(0600;npm 安装时为 ~/.dsh-remote/)
20
20
  * 2. 生成自启动服务(macOS launchd / Linux systemd),随 dsh web(3080) 存活自动保活
21
21
  * 3. 自动把远程控制插件装进 dsh web 设置页(若检测到 profile)
22
- * 4. 登录在设置页完成: dsh-remote settings(手机号+密码,或自建密钥)
22
+ * 4. 登录/连接配置在 dsh web → 设置 → 「远程控制」面板完成(SaaS 注册登录 / 自建切换)
23
+ * 自建 CLI 用户也可用 `dsh-remote setup --server … --key …`(无需再打开设置页)
23
24
  */
24
25
 
25
- import http from "node:http";
26
26
  import fs from "node:fs";
27
27
  import os from "node:os";
28
28
  import path from "node:path";
@@ -35,7 +35,6 @@ const IS_NPM_INSTALL = THIS_DIR.includes(`${path.sep}node_modules${path.sep}`);
35
35
  // 配置目录:npm 安装时放在用户目录(node_modules 内不可写);仓库开发时放在仓库根。
36
36
  const CONFIG_DIR = process.env.DSH_RELAY_DIR || (IS_NPM_INSTALL ? path.join(os.homedir(), ".dsh-remote") : THIS_DIR);
37
37
  const CONFIG_PATH = path.join(CONFIG_DIR, ".dsh-config.json");
38
- const SETTINGS_PORT = 3499;
39
38
  // 默认云端服务地址(服务商 SaaS 入口;自建用户用 --server/--key 指向自己的 router)
40
39
  const DEFAULT_API = "https://n.risegao.cn:13443/relay-api";
41
40
  const DEFAULT_APP_URL = "https://n.risegao.cn:13443/app/";
@@ -281,97 +280,20 @@ function installAutostart() {
281
280
  return { path: svcPath, status: r };
282
281
  }
283
282
 
284
- // ---------- 设置页(本地 HTTP:远程地址 + 账号/自建配置) ----------
285
- function serveSettings() {
286
- const cfg = loadConfig();
287
- const server = http.createServer(async (req, res) => {
288
- const url = new URL(req.url, `http://127.0.0.1:${SETTINGS_PORT}`);
289
- const send = (code, body, type = "text/html") => {
290
- res.writeHead(code, { "Content-Type": type + "; charset=utf-8" });
291
- res.end(body);
292
- };
293
-
294
- if (req.method === "POST" && url.pathname === "/api/config") {
295
- let raw = "";
296
- for await (const c of req) raw += c;
297
- try {
298
- const body = JSON.parse(raw);
299
- const local = Boolean(body.local_key || body.server);
300
- if (local) {
301
- if (!body.server || !body.local_key) {
302
- return send(400, JSON.stringify({ ok: false, message: "自建模式需要服务器地址与访问密钥" }), "application/json");
303
- }
304
- cfg.tunnel_url = normalizeTunnelUrl(body.server);
305
- cfg.local_key = String(body.local_key).trim();
306
- delete cfg.phone; delete cfg.password;
307
- } else {
308
- if (!body.phone || !body.password) {
309
- return send(400, JSON.stringify({ ok: false, message: "SaaS 模式需要手机号与密码" }), "application/json");
310
- }
311
- cfg.phone = body.phone; cfg.password = body.password;
312
- applySaaSMode(cfg); // 清自建残留,api/tunnel 权威重算
313
- }
314
- // 自动获取服务端下发的 bridge_secret(device-login 共享密钥,一键安装开箱即用)
315
- if (!cfg.bridge_secret && !cfg.local_key) {
316
- const pub = await fetchPublicConfig(cfg.api_url || DEFAULT_API);
317
- if (pub.bridge_secret) cfg.bridge_secret = String(pub.bridge_secret);
318
- }
319
- saveConfig(cfg);
320
- const r = restartBridgeService();
321
- return send(200, JSON.stringify({ ok: true, service: r.ok ? "running" : (r.status || "failed") }), "application/json");
322
- } catch { return send(400, JSON.stringify({ ok: false, message: "JSON 解析失败" }), "application/json"); }
323
- }
283
+ // ---------- settings:旧独立设置页已移除(引导到 dsh web 插件面板) ----------
284
+ // 云服务用户在 dsh web → 设置 → 「远程控制」面板即可注册/登录(自建切换也在此面板);
285
+ // 独立设置页(127.0.0.1:3499)与面板功能完全重复、且暴露自建表单给普通用户造成困惑,已移除。
286
+ // 保留 `dsh-remote settings` 命令为“引导提示”,避免旧脚本/旧文档直接调它时报错。
287
+ function settingsHint() {
288
+ console.log(`
289
+ dsh-remote:独立的本地设置页已移除。
324
290
 
325
- const mode = cfg.local_key ? "自建服务" : "SaaS 云端服务";
326
- const pub = await fetchPublicConfig(cfg.api_url || DEFAULT_API);
327
- const remoteUrl = pub.app_url || (cfg.local_key ? (cfg.tunnel_url || "") : DEFAULT_APP_URL);
328
-
329
- const html = `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"/>
330
- <meta name="viewport" content="width=device-width,initial-scale=1"/>
331
- <title>dsh-remote 设置</title>
332
- <style>
333
- body{font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;background:#0d1117;color:#e6edf3;max-width:520px;margin:0 auto;padding:24px}
334
- h1{font-size:18px}label{display:block;font-size:13px;color:#8b949e;margin:14px 0 6px}
335
- input{width:100%;padding:11px 13px;border-radius:8px;border:1px solid #30363d;background:#161b22;color:#e6edf3;font-size:15px;box-sizing:border-box}
336
- button{width:100%;padding:13px;border-radius:8px;border:none;background:#2f81f7;color:#fff;font-size:15px;font-weight:600;cursor:pointer;margin-top:16px}
337
- .card{background:#161b22;border:1px solid #30363d;border-radius:12px;padding:18px;margin-bottom:16px}
338
- .url{background:#010409;border:1px solid #30363d;border-radius:8px;padding:12px;font-family:monospace;font-size:14px;word-break:break-all}
339
- .msg{font-size:13px;margin-top:10px;min-height:18px}.ok{color:#3fb950}.err{color:#f85149}
340
- </style></head><body>
341
- <h1>dsh-remote 设置</h1>
342
- <div class="card"><h3 style="margin:0 0 8px">📱 远程控制地址(当前模式:${mode})</h3>
343
- <div class="url">${remoteUrl || "(未配置)"}</div>
344
- <div style="font-size:12px;color:#8b949e;margin-top:8px">手机浏览器打开此地址,即可远程控制本机 dsh web。</div></div>
345
- <div class="card"><h3 style="margin:0 0 4px">🔑 连接配置</h3>
346
- <div style="font-size:12px;color:#8b949e;margin-bottom:8px">二选一:填手机号密码(SaaS),或填服务器地址+访问密钥(自建)。</div>
347
- <label>SaaS 手机号</label><input id="phone" value="${cfg.phone || ""}" autocomplete="tel"/>
348
- <label>SaaS 密码</label><input id="pass" type="password" placeholder="••••••••" autocomplete="current-password"/>
349
- <div style="height:1px;background:#30363d;margin:16px 0"></div>
350
- <label>自建服务器地址(wss://host:port)</label><input id="server" value="${cfg.tunnel_url || ""}" placeholder="wss://relay.example.com"/>
351
- <label>自建访问密钥</label><input id="lkey" type="password" value="${cfg.local_key || ""}" placeholder="访问密钥"/>
352
- <button onclick="save()">保存并生效</button>
353
- <div class="msg" id="msg"></div></div>
354
- <script>
355
- async function save(){
356
- const m=document.getElementById("msg");m.className="msg";m.textContent="保存中...";
357
- const local = document.getElementById("lkey").value.trim() !== "" || document.getElementById("server").value.trim() !== "";
358
- try{
359
- const r=await fetch("/api/config",{method:"POST",headers:{"content-type":"application/json"},
360
- body:JSON.stringify(local
361
- ? {server:document.getElementById("server").value.trim(),local_key:document.getElementById("lkey").value.trim()}
362
- : {phone:document.getElementById("phone").value.trim(),password:document.getElementById("pass").value})});
363
- const d=await r.json();
364
- if(d.ok){m.className="msg ok";m.textContent = d.service==="running" ? "✅ 已保存并生效,无需手动重启" : "✅ 已保存(服务状态: "+(d.service||"未知")+",可运行 dsh-remote setup 修复)";}
365
- else{m.className="msg err";m.textContent=d.message||"保存失败";}
366
- }catch(e){m.className="msg err";m.textContent="保存失败: "+e.message;}
367
- }
368
- </script></body></html>`;
369
- return send(200, html);
370
- });
371
- server.listen(SETTINGS_PORT, "127.0.0.1", () => {
372
- console.log(`\n✅ 设置页已打开: http://127.0.0.1:${SETTINGS_PORT}`);
373
- console.log(" 在浏览器中配置账号或自建连接,查看远程控制地址。Ctrl-C 关闭。\n");
374
- });
291
+ 请直接在 dsh web 里完成登录/连接配置(无需任何命令):
292
+ 打开 dsh web 设置 「远程控制」→ 注册或登录手机号即可(自建模式切换也在该面板)。
293
+
294
+ 自建用户若偏好命令行,可用:
295
+ dsh-remote setup --server wss://你的域名:端口 --key 访问密钥
296
+ `);
375
297
  }
376
298
 
377
299
  // ---------- run:前台跑 bridge(带配置 + 自启动 watcher) ----------
@@ -400,7 +322,7 @@ async function runBridge() {
400
322
  if (!saas && !local) {
401
323
  if (!warnedNoLogin) {
402
324
  warnedNoLogin = true;
403
- console.log("⚠️ 尚未登录:打开设置页 `dsh-remote settings` 登录账号(或配置自建密钥)后自动启动。");
325
+ console.log("⚠️ 尚未登录:请打开 dsh web → 设置 → 「远程控制」,注册/登录手机号(或切到自建模式)后自动启动。");
404
326
  }
405
327
  return;
406
328
  }
@@ -802,7 +724,7 @@ const raw = process.argv[2];
802
724
  const cmd = raw && !raw.startsWith("-") ? raw : "setup";
803
725
  const args = raw && !raw.startsWith("-") ? process.argv.slice(3) : process.argv.slice(2);
804
726
  if (cmd === "setup" || cmd === "install") await setup(args);
805
- else if (cmd === "settings") serveSettings();
727
+ else if (cmd === "settings") settingsHint();
806
728
  else if (cmd === "run") await runBridge();
807
729
  else if (cmd === "plugin") await pluginCmd(process.argv.slice(3));
808
730
  else if (cmd === "status") {
@@ -811,13 +733,13 @@ else if (cmd === "status") {
811
733
  console.log("配置文件:", CONFIG_PATH);
812
734
  console.log("连接模式:", local ? `自建服务(${cfg.tunnel_url || "未设置服务器地址"})` : `SaaS 云端服务(${cfg.phone || "未配置账号"})`);
813
735
  console.log("API:", cfg.api_url || (local ? "(自建模式无需账号 API)" : DEFAULT_API));
814
- console.log("远程地址: 运行 settings 查看最新");
736
+ console.log("远程地址/登录: 打开 dsh web → 设置 → 「远程控制」查看与操作");
815
737
  } else {
816
738
  console.log(`dsh-remote — 手机远程控制 dsh web(隧道模式)
817
739
 
818
740
  用法:
819
741
  dsh-remote 一键安装(默认命令,无需任何参数;含插件与自启动)
820
- dsh-remote settings 打开本地设置页(登录账号 / 自建配置)
742
+ dsh-remote settings 显示登录/连接配置指引(独立设置页已移除)
821
743
  dsh-remote run 前台运行 bridge(调试)
822
744
  dsh-remote status 查看配置与服务状态
823
745
  dsh-remote plugin 手动安装 dsh web 远程控制插件(--uninstall 卸载)
@@ -825,7 +747,8 @@ else if (cmd === "status") {
825
747
  自建模式(可选):
826
748
  dsh-remote setup --server wss://你的域名:端口 --key 访问密钥
827
749
 
828
- 登录: 安装后运行 \`dsh-remote settings\`,用手机号+密码登录(或配置自建密钥)。
750
+ 登录/连接配置: 打开 dsh web → 设置 → 「远程控制」→ 注册或登录手机号即可
751
+ (自建用户切「自建服务」标签或直接用上方 setup 命令,无需另开页面)。
829
752
  文档: ${REPO_URL}
830
753
  `);
831
754
  process.exit(cmd === "help" ? 0 : 1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrrisega/dsh-remote",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "description": "手机远程控制 DeepSeek Harness · Remote control DeepSeek Harness (dsh web) from any phone browser — 100% 全功能 App 级体验:发消息、看工具执行、审批权限、改设置、管凭据,含特权操作,免内网穿透。一条命令安装 npx @mrrisega/dsh-remote。Mobile remote control for DSH, self-host or SaaS, no server needed on LAN.",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -837,7 +837,7 @@ async function proxyFeedback(relayDir, req, res, pathname) {
837
837
  // ---------- 自管理:版本 / 在线更新 / 彻底卸载(面板内“版本与更新”卡片) ----------
838
838
 
839
839
  /** 插件自身发布版本(与 dsh-remote 根包同步递增)。 */
840
- const PLUGIN_VERSION = "0.4.8";
840
+ const PLUGIN_VERSION = "0.4.9";
841
841
  const UPDATE_LOG = ".dsh-update.log";
842
842
  const UPDATE_MARKER = ".dsh-update-running";
843
843