@mrrisega/dsh-remote 0.3.0 → 0.3.1

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
@@ -17,6 +17,16 @@ dsh-remote 是一个轻量的**隧道模式**远程控制方案:电脑端运
17
17
  └→ bridge (电脑端) → 127.0.0.1:3080 (dsh web)
18
18
  ```
19
19
 
20
+ ## 界面预览
21
+
22
+ | 手机端进入 dsh web,100% 还原电脑端体验 | 手机端密钥登录后的在线设备列表 |
23
+ |---|---|
24
+ | ![手机端进入 dsh web](https://cdn.jsdelivr.net/gh/mrRisega/dsh-remote@main/image/phone-mirror.png) | ![手机端在线设备列表](https://cdn.jsdelivr.net/gh/mrRisega/dsh-remote@main/image/phone-devices.png) |
25
+
26
+ | 电脑端 dsh web 插件设置(自建服务模式) |
27
+ |---|
28
+ | ![客户端设置-自建服务](https://cdn.jsdelivr.net/gh/mrRisega/dsh-remote@main/image/selfhost-settings.png) |
29
+
20
30
  ## 两个版本
21
31
 
22
32
  | | 开源版(本仓库) | SaaS 云服务版 |
@@ -29,6 +39,10 @@ dsh-remote 是一个轻量的**隧道模式**远程控制方案:电脑端运
29
39
 
30
40
  两者可随时切换:电脑端插件面板「连接模式」一键切换,互不影响。
31
41
 
42
+ > 👉 **不想自建服务器 / 没有公网 IP?** 直接使用**官方云服务版**(托管 relay,无公网、4G、异地也稳定,多设备 + 超管后台):
43
+ > **https://n.risegao.cn:13443/app/** (免费版 + PRO ¥19/月 + Pro Max ¥49/月,新用户送 7 天 PRO)。
44
+ > 客户端仍是同一条命令安装 `npx @mrrisega/dsh-remote`,登录后选择「云服务模式」即可。
45
+
32
46
  ## 安装
33
47
 
34
48
  需要 Node.js ≥ 20。电脑端**一条命令**完成安装:自动安装 bridge 与 dsh web 插件、
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "@mrrisega/dsh-remote",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Remote control for DeepSeek Harness (dsh web) from any phone browser: tunnel-mode relay client with one-command install, self-hosting support, and a dsh web plugin panel",
5
5
  "type": "module",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
7
7
  "private": false,
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/mrRisega/dsh-remote.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/mrRisega/dsh-remote/issues"
14
+ },
15
+ "homepage": "https://github.com/mrRisega/dsh-remote#readme",
8
16
  "bin": {
9
17
  "dsh-remote": "dsh-setup.mjs"
10
18
  },
@@ -0,0 +1,7 @@
1
+ # dsh-remote-ui — dsh web 远程控制插件(dsh-remote 的插件半)
2
+ # 提供设置页「远程控制」面板与同源 /dsh-remote/* 路由。
3
+ # relayDir 默认取 ~/.dsh-remote(与 npx @mrrisega/dsh-remote 写入的
4
+ # .dsh-config.json 相同),也可在面板或 entry config 中覆盖。
5
+ - insert:
6
+ - id: dsh-remote-ui
7
+ name: 'dsh-remote-ui'
@@ -11,7 +11,7 @@
11
11
  // · 登录要求图形验证码;注册要求两次密码 + 图形验证码
12
12
  // · 远程地址展示 + bridge 状态与启停开关 + 关于 dsh-remote 说明卡片
13
13
  // - 首次安装引导:设置页栏目旁小红点(localStorage dsh-remote-seen-dot 控制)
14
- // - shell.overlay:满意度弹窗(安装体验约 10 分钟后弹出)
14
+ // - shell.overlay:满意度弹窗(安装体验至少 1 小时后弹出,只弹一次)
15
15
  // 所有数据经同源 /dsh-remote/* 宿主路由读写(node 半提供)。
16
16
  window.__ModuleLoader__.load({
17
17
  id: "dsh-remote-ui",
@@ -105,7 +105,7 @@ window.__ModuleLoader__.load({
105
105
  ".dru-fb-reply-text{font-size:12.5px;color:#1f2328;white-space:pre-wrap;word-break:break-word;flex:1}",
106
106
  ".dru-fb-reply-input{width:100%;box-sizing:border-box;padding:7px 10px;border-radius:8px;border:1px solid #d0d7de;background:#ffffff;font-size:12.5px;font-family:inherit;resize:vertical;min-height:44px}",
107
107
  ".dru-fb-empty{font-size:12.5px;color:#8c959f;text-align:center;padding:14px 0}",
108
- // ── 满意度弹窗(10 分钟体验后) ──
108
+ // ── 满意度弹窗(1 小时体验后,只弹一次) ──
109
109
  ".dru-popup{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:2147482000;display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box}",
110
110
  ".dru-popup-card{width:min(400px,calc(100vw - 48px));background:#ffffff;color:#1f2328;border:1px solid #d0d7de;border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.45);font-size:14px;line-height:1.5;font-family:var(--dsw-font-family,-apple-system,'PingFang SC','Microsoft YaHei',sans-serif);overflow:hidden}",
111
111
  ".dru-popup-body{padding:22px 22px 16px;text-align:center}",
@@ -213,8 +213,7 @@ window.__ModuleLoader__.load({
213
213
  // ── 用户反馈模块:本地状态(thread 令牌 / 弹窗节流) ───────────────────
214
214
  var FB_THREADS_KEY = "dsh-feedback-threads";
215
215
  var FB_POPUP_KEY = "dsh-feedback-popup";
216
- var FB_POPUP_DELAY_MS = 10 * 60 * 1000; // 安装/体验后约 10 分钟弹窗
217
- var FB_POPUP_LATER_MS = 24 * 3600 * 1000; // “稍后再说”延迟 1 天
216
+ var FB_POPUP_DELAY_MS = 60 * 60 * 1000; // 安装/体验后至少 1 小时才弹窗(只弹一次)
218
217
  var FB_CATEGORIES = [
219
218
  { value: "feature", label: "功能类" },
220
219
  { value: "bug", label: "Bug 类" },
@@ -261,32 +260,9 @@ window.__ModuleLoader__.load({
261
260
  FB_STATUS_LABEL[status] || status || "待处理");
262
261
  }
263
262
 
264
- /** 提交表单用验证码(服务端要求匿名首条必填)。
265
- * 状态机:idle → loading → ready | error;区域永远可见,失败可点击重试。 */
266
- function FbCaptcha(props) {
267
- var st = props.state || "idle";
268
- var ready = st === "ready" && props.cap && props.cap.id;
269
- var box;
270
- if (ready) {
271
- box = h("div", { className: "dru-captcha-box", title: "看不清?点击刷新", onClick: props.onRefresh,
272
- dangerouslySetInnerHTML: props.cap.svg && props.cap.svg.indexOf("<svg") === 0 ? { __html: props.cap.svg } : void 0 },
273
- props.cap.svg && props.cap.svg.indexOf("<svg") !== 0 ? props.cap.svg : null);
274
- } else if (st === "loading") {
275
- box = h("div", { className: "dru-captcha-box" }, h("span", { className: "dru-hint" }, "验证码加载中…"));
276
- } else if (st === "error") {
277
- box = h("div", { className: "dru-captcha-box", title: "点击重试", onClick: props.onRefresh },
278
- h("span", { className: "dru-hint", style: { color: "#cf222e" } }, "加载失败,点击重试"));
279
- } else {
280
- box = h("div", { className: "dru-captcha-box", title: "点击加载验证码", onClick: props.onRefresh },
281
- h("span", { className: "dru-hint" }, "点击加载验证码"));
282
- }
283
- return h("div", { className: "dru-captcha", style: { marginBottom: 10 } },
284
- h("input", { className: "dru-input", value: props.answer, placeholder: "图中 4 位数字", autoComplete: "off", inputMode: "numeric", maxLength: 4, disabled: !ready, onChange: function (e) { props.setAnswer(e.target.value); } }),
285
- box
286
- );
287
- }
288
-
289
- /** 面板内的“用户反馈”卡片(提交 + 我的反馈 双 tab)。 */
263
+ /** 面板内的“用户反馈”卡片(提交 + 我的反馈 双 tab)。
264
+ * 匿名(自建/未登录)不要求任何验证码:仅填写内容即可提交,
265
+ * 服务端只记录 IP / 浏览器标识,防刷由服务端限流兜底。 */
290
266
  function FeedbackCard(props) {
291
267
  var cfgArr = useState(null); var cfg = cfgArr[0]; var setCfg = cfgArr[1];
292
268
  var fbAuthArr = useState("anonymous"); var fbAuth = fbAuthArr[0]; var setFbAuth = fbAuthArr[1];
@@ -295,9 +271,6 @@ window.__ModuleLoader__.load({
295
271
  var titleArr = useState(""); var fbTitle = titleArr[0]; var setFbTitle = titleArr[1];
296
272
  var contentArr = useState(""); var fbContent = contentArr[0]; var setFbContent = contentArr[1];
297
273
  var contactArr = useState(""); var contact = contactArr[0]; var setContact = contactArr[1];
298
- var capArr = useState(null); var cap = capArr[0]; var setCap = capArr[1];
299
- var capStateArr = useState("idle"); var capState = capStateArr[0]; var setCapState = capStateArr[1];
300
- var capTxtArr = useState(""); var capTxt = capTxtArr[0]; var setCapTxt = capTxtArr[1];
301
274
  var threadsArr = useState(fbLoadThreads()); var threads = threadsArr[0]; var setThreads = threadsArr[1];
302
275
  var openIdArr = useState(""); var openId = openIdArr[0]; var setOpenId = openIdArr[1];
303
276
  var threadDataArr = useState(null); var threadData = threadDataArr[0]; var setThreadData = threadDataArr[1];
@@ -309,25 +282,13 @@ window.__ModuleLoader__.load({
309
282
  var loadCfg = useCallback(function () {
310
283
  api("/dsh-remote/feedback-config").then(function (b) {
311
284
  setCfg(b);
312
- // 登录态(节点半自动附加 JWT)免验证码;匿名才需要图形验证码
285
+ // 登录态(节点半自动附加 JWT)→ 提交自动带上账号身份;
286
+ // 匿名(自建/未登录)→ 不要求任何验证码,服务端只记录 IP / 浏览器标识。
313
287
  setFbAuth(b.auth === "account" ? "account" : "anonymous");
314
- if (b.auth !== "account") loadCaptcha();
315
288
  if (!b.reachable) setMsg("warn", "反馈服务未连接,请检查网络或 feedback_url 配置");
316
289
  }).catch(function (e) { setCfg({ reachable: false }); setMsg("warn", "反馈服务未连接:" + e.message); });
317
290
  }, []);
318
291
 
319
- function loadCaptcha() {
320
- setCapState("loading");
321
- setCapTxt("");
322
- fbApi("/feedback/captcha").then(function (b) {
323
- var cid = b.captcha_id || b.id; if (cid) { setCap({ id: cid, svg: b.svg || "" }); setCapState("ready"); }
324
- else { setCap(null); setCapState("error"); }
325
- }).catch(function (e) {
326
- setCap(null); setCapState("error");
327
- setMsg("err", "验证码加载失败:" + e.message);
328
- });
329
- }
330
-
331
292
  function loadThread(id) {
332
293
  var t = threads.filter(function (x) { return x.id === id; })[0];
333
294
  if (!t) return;
@@ -344,15 +305,6 @@ window.__ModuleLoader__.load({
344
305
  var doSubmit = function () {
345
306
  if (!fbContent.trim()) { setMsg("err", "请填写反馈内容"); return; }
346
307
  if (fbContent.length > 2000) { setMsg("err", "内容不能超过 2000 字"); return; }
347
- var accountAuth = fbAuth === "account";
348
- if (!accountAuth) {
349
- if (capState !== "ready" || !cap || !cap.id) {
350
- loadCaptcha();
351
- setMsg("err", "请先输入验证码(图中 4 位数字,点图片可刷新)");
352
- return;
353
- }
354
- if (!capTxt.trim()) { setMsg("err", "请输入验证码(图中 4 位数字)"); return; }
355
- }
356
308
  setBusy("submit");
357
309
  var payload = {
358
310
  kind: "feedback",
@@ -361,22 +313,17 @@ window.__ModuleLoader__.load({
361
313
  content: fbContent.trim(),
362
314
  contact: contact.trim() || (cfg && cfg.phone ? cfg.phone : ""),
363
315
  };
364
- if (!accountAuth) {
365
- payload.captcha_id = cap.id;
366
- payload.captcha_answer = capTxt.trim();
367
- }
368
316
  fbApi("/feedback", { method: "POST", body: JSON.stringify(payload) })
369
317
  .then(function (b) {
370
318
  fbRememberThread(b.feedback.id, b.thread_token);
371
319
  setThreads(fbLoadThreads());
372
- setFbTitle(""); setFbContent(""); setContact(""); setCap(null); setCapState("idle"); setCapTxt("");
320
+ setFbTitle(""); setFbContent(""); setContact("");
373
321
  setMsg("ok", "✅ 反馈已提交,可在「我的反馈」查看回复");
374
322
  setTab("mine");
375
323
  })
376
324
  .catch(function (e) {
377
325
  var errBody = e.body && e.body.error;
378
- if (errBody && errBody.code === "captcha_invalid") { setCapTxt(""); loadCaptcha(); setMsg("err", "验证码错误或已过期,请重新输入"); }
379
- else if (errBody && errBody.code === "rate_limited") setMsg("err", "今天提交次数已达上限,请明天再试");
326
+ if (errBody && errBody.code === "rate_limited") setMsg("err", "今天提交次数已达上限,请明天再试");
380
327
  else setMsg("err", "提交失败:" + (errBody && errBody.message ? errBody.message : e.message));
381
328
  })
382
329
  .finally(function () { setBusy(""); });
@@ -434,9 +381,10 @@ window.__ModuleLoader__.load({
434
381
  h("label", null, "联系方式(可选)"),
435
382
  h("input", { className: "dru-input", type: "text", value: contact, maxLength: 120, placeholder: cfg && cfg.phone ? "已登录手机号:" + cfg.phone : "邮箱/手机号,便于我们跟进", onChange: function (e) { setContact(e.target.value); } })
436
383
  ),
437
- fbAuth === "account"
438
- ? h("div", { className: "dru-hint", style: { marginBottom: 10 } }, "已登录账号,提交反馈无需验证码。")
439
- : FbCaptcha({ state: capState, cap: cap, answer: capTxt, setAnswer: setCapTxt, onRefresh: loadCaptcha }),
384
+ h("div", { className: "dru-hint", style: { marginBottom: 10 } },
385
+ fbAuth === "account"
386
+ ? "已登录账号,提交反馈会带上你的身份信息。"
387
+ : "匿名反馈:无需输入任何验证码,上报仅记录 IP 与浏览器标识。"),
440
388
  h("button", { type: "button", className: "dru-btn dru-btn-primary", style: { width: "100%" }, disabled: busy !== "", onClick: doSubmit }, busy === "submit" ? "提交中…" : "提交反馈"),
441
389
  fbMsg && h("div", { className: "dru-msg dru-msg-" + fbMsg.kind }, fbMsg.text)
442
390
  )
@@ -498,7 +446,7 @@ window.__ModuleLoader__.load({
498
446
  function subscribePopup(cb) { popupListeners.add(cb); return function () { popupListeners.delete(cb); }; }
499
447
  function usePopupOpen() { return useSyncExternalStore(subscribePopup, function () { return popupOpen; }); }
500
448
 
501
- /** 首次安装时间戳(首次观察到 bridge 运行时记下,便于“先体验 10 分钟”)。 */
449
+ /** 首次安装时间戳(首次观察到 bridge 运行时记下,便于“先用满 1 小时再评价”)。 */
502
450
  var fbFirstSeenAt = null;
503
451
  function fbEnsureFirstSeen() {
504
452
  var s = fbPopState();
@@ -517,7 +465,8 @@ window.__ModuleLoader__.load({
517
465
  setPopupOpen(true);
518
466
  }
519
467
  function fbPopupLater() {
520
- fbSavePopState({ state: "pending", firstSeen: fbFirstSeenAt || Date.now(), nextAt: Date.now() + FB_POPUP_LATER_MS });
468
+ // 只弹一次:关闭即视为本轮安装的评价流程结束,不再自动重复弹出
469
+ fbSavePopState({ state: "done", firstSeen: fbFirstSeenAt || Date.now(), nextAt: 0 });
521
470
  setPopupOpen(false);
522
471
  }
523
472
  function fbPopupDone() {
@@ -531,9 +480,6 @@ window.__ModuleLoader__.load({
531
480
  var ratingArr = useState(null); var rating = ratingArr[0]; var setRating = ratingArr[1];
532
481
  var noteArr = useState(""); var note = noteArr[0]; var setNote = noteArr[1];
533
482
  var recommendArr = useState(null); var recommend = recommendArr[0]; var setRecommend = recommendArr[1];
534
- var capArr = useState(null); var cap = capArr[0]; var setCap = capArr[1];
535
- var capStateArr = useState("idle"); var capState = capStateArr[0]; var setCapState = capStateArr[1];
536
- var capTxtArr = useState(""); var capTxt = capTxtArr[0]; var setCapTxt = capTxtArr[1];
537
483
  var busyArr = useState(""); var busy = busyArr[0]; var setBusy = busyArr[1];
538
484
  var msgArr = useState(null); var message = msgArr[0]; var setMessage = msgArr[1];
539
485
  var fbAuthArr = useState("anonymous"); var fbAuth = fbAuthArr[0]; var setFbAuth = fbAuthArr[1];
@@ -541,18 +487,6 @@ window.__ModuleLoader__.load({
541
487
  var inviteArr = useState(null); var popupInvite = inviteArr[0]; var setPopupInvite = inviteArr[1];
542
488
  var inviteCopiedArr = useState(false); var inviteCopied = inviteCopiedArr[0]; var setInviteCopied = inviteCopiedArr[1];
543
489
 
544
- function loadPopupCaptcha() {
545
- setCapState("loading");
546
- setCapTxt("");
547
- fbApi("/feedback/captcha").then(function (b) {
548
- var cid = b.captcha_id || b.id; if (cid) { setCap({ id: cid, svg: b.svg || "" }); setCapState("ready"); }
549
- else { setCap(null); setCapState("error"); }
550
- }).catch(function () {
551
- setCap(null); setCapState("error");
552
- setMessage({ kind: "err", text: "验证码加载失败,可点击验证码区域重试" });
553
- });
554
- }
555
-
556
490
  /** 预取邀请信息(已登录且有邀请码时生成专属链接)。 */
557
491
  function loadPopupInvite() {
558
492
  if (popupInvite) return;
@@ -568,29 +502,19 @@ window.__ModuleLoader__.load({
568
502
 
569
503
  useEffect(function () {
570
504
  if (!open) return;
571
- // 登录态(节点半自动附加 JWT)免验证码;匿名才需要图形验证码
505
+ // 登录态(节点半自动附加 JWT)→ 提交自动带上账号身份;
506
+ // 匿名(自建/未登录)→ 不要求任何验证码,服务端只记录 IP / 浏览器标识。
572
507
  api("/dsh-remote/feedback-config").then(function (b) {
573
508
  setFbAuth(b.auth === "account" ? "account" : "anonymous");
574
- if (b.auth === "account") { setCap(null); setCapState("idle"); }
575
509
  }).catch(function () { setFbAuth("anonymous"); });
576
510
  // eslint-disable-next-line react-hooks/exhaustive-deps
577
511
  }, [open]);
578
512
 
579
- useEffect(function () {
580
- if (open && step === "rate" && capState === "idle" && fbAuth !== "account") loadPopupCaptcha();
581
- // eslint-disable-next-line react-hooks/exhaustive-deps
582
- }, [open, step, capState, fbAuth]);
583
-
584
513
  if (!open) return null;
585
514
 
586
515
  var doSubmit = function () {
587
516
  if (rating === null) { setMessage({ kind: "err", text: "请先选择满意度" }); return; }
588
517
  if (step === "rate") { setStep("recommend"); return; }
589
- var accountAuth = fbAuth === "account";
590
- if (!accountAuth) {
591
- if (capState !== "ready" || !cap || !cap.id) { loadPopupCaptcha(); setMessage({ kind: "err", text: "请先输入验证码" }); return; }
592
- if (!capTxt.trim()) { setMessage({ kind: "err", text: "请输入验证码(图中 4 位数字)" }); return; }
593
- }
594
518
  setBusy("submit");
595
519
  var payload = {
596
520
  kind: "rating",
@@ -599,10 +523,6 @@ window.__ModuleLoader__.load({
599
523
  rating: rating,
600
524
  recommend: recommend === true ? 1 : 0,
601
525
  };
602
- if (!accountAuth) {
603
- payload.captcha_id = cap.id;
604
- payload.captcha_answer = capTxt.trim();
605
- }
606
526
  fbApi("/feedback", { method: "POST", body: JSON.stringify(payload) })
607
527
  .then(function (b) {
608
528
  fbRememberThread(b.feedback.id, b.thread_token);
@@ -610,8 +530,7 @@ window.__ModuleLoader__.load({
610
530
  })
611
531
  .catch(function (e) {
612
532
  var errBody = e.body && e.body.error;
613
- if (errBody && errBody.code === "captcha_invalid") { setStep("rate"); setCapTxt(""); loadPopupCaptcha(); setMessage({ kind: "err", text: "验证码错误或已过期,请重新输入" }); }
614
- else if (errBody && errBody.code === "rate_limited") { fbPopupLater(); setMessage({ kind: "err", text: "今日提交已达上限,明天再来吧" }); }
533
+ if (errBody && errBody.code === "rate_limited") { fbPopupLater(); setMessage({ kind: "err", text: "今日提交已达上限,明天再来吧" }); }
615
534
  else setMessage({ kind: "err", text: "提交失败:" + ((errBody && errBody.message) || e.message) + "(可稍后再试)" });
616
535
  })
617
536
  .finally(function () { setBusy(""); });
@@ -624,7 +543,7 @@ window.__ModuleLoader__.load({
624
543
  ? h("div", null,
625
544
  h("div", { className: "dru-popup-icon" }, "😊"),
626
545
  h("div", { className: "dru-popup-title" }, "您对远程控制功能满意吗?"),
627
- h("div", { className: "dru-popup-sub" }, "用了 10 分钟,说说真实感受吧(1 分钟搞定)"),
546
+ h("div", { className: "dru-popup-sub" }, "使用体验已满 1 小时,说说真实感受吧(1 分钟搞定)"),
628
547
  h("div", { className: "dru-popup-rate" },
629
548
  [ [5, "😄", "很满意"], [3, "😐", "一般"], [1, "😞", "不满意"] ].map(function (r) {
630
549
  return h("button", { key: r[0], type: "button", className: rating === r[0] ? "sel" : "", onClick: function () { setRating(r[0]); setMessage(null); } },
@@ -632,9 +551,10 @@ window.__ModuleLoader__.load({
632
551
  })
633
552
  ),
634
553
  h("textarea", { className: "dru-popup-textarea", value: note, maxLength: 2000, placeholder: "说说想法或遇到的问题(可选)…", onChange: function (e) { setNote(e.target.value); } }),
635
- fbAuth === "account"
636
- ? h("div", { className: "dru-hint", style: { marginTop: 10 } }, "已登录账号,提交无需验证码。")
637
- : FbCaptcha({ state: capState, cap: cap, answer: capTxt, setAnswer: setCapTxt, onRefresh: loadPopupCaptcha }),
554
+ h("div", { className: "dru-hint", style: { marginTop: 10 } },
555
+ fbAuth === "account"
556
+ ? "已登录账号,本次评价会带上你的身份信息。"
557
+ : "匿名评价:只需填上面内容,无需任何验证码;上报会记录 IP 与浏览器标识。"),
638
558
  message && h("div", { className: "dru-msg dru-msg-" + message.kind }, message.text),
639
559
  h("div", { className: "dru-popup-actions" },
640
560
  h("button", { type: "button", className: "dru-btn dru-btn-primary", disabled: busy !== "", onClick: doSubmit }, "下一步")
@@ -676,7 +596,7 @@ window.__ModuleLoader__.load({
676
596
  )
677
597
  ),
678
598
  h("div", { className: "dru-popup-foot" },
679
- h("button", { type: "button", onClick: fbPopupLater }, "稍后再说"),
599
+ h("button", { type: "button", title: "关闭本轮评价,之后不再自动弹出", onClick: fbPopupLater }, "暂不评价"),
680
600
  h("button", { type: "button", onClick: fbPopupDone }, "不再提示")
681
601
  )
682
602
  )
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "dsh-remote-ui",
3
3
  "version": "0.1.0",
4
- "description": "dsh web 远程控制插件:设置页「远程控制」栏目(settings.section 官方扩展点,位于 Agent 预设下方)+ 配置面板 + bridge 启停 + 反馈/邀请/满意度(双半插件:node 半提供 /dsh-remote 宿主 API,浏览器半提供 UI",
4
+ "description": "Remote control for dsh web from a phone browser: an in-harness Settings panel (cloud/self-hosted mode tabs, account login, bridge start/stop, feedback) plus same-origin /dsh-remote relay routes; the desktop bridge and self-hosted relay-router shipped with this repo tunnel the local dsh web to a phone PWA with access-key auth, live device list and optional traffic quotas. · dsh web 远程控制插件:设置页「远程控制」栏目(settings.section 官方扩展点)+ 配置面板 + bridge 启停 + 反馈/邀请/满意度(双半插件:node 半提供 /dsh-remote 宿主 API,浏览器半提供 UI)。",
5
5
  "type": "module",
6
- "private": true,
7
6
  "main": "lib/index.js",
8
7
  "exports": {
9
8
  ".": {
@@ -14,7 +13,16 @@
14
13
  },
15
14
  "./package.json": "./package.json"
16
15
  },
16
+ "files": [
17
+ "lib",
18
+ "cordis.patch.yml",
19
+ "screenshots.json",
20
+ "README.md"
21
+ ],
17
22
  "dsh": {
23
+ "bundle": {
24
+ "patch": "./cordis.patch.yml"
25
+ },
18
26
  "client": {
19
27
  "platform": "web",
20
28
  "inject": [
@@ -22,5 +30,14 @@
22
30
  ]
23
31
  }
24
32
  },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/mrRisega/dsh-remote.git",
36
+ "directory": "packages/dsh-remote-ui"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/mrRisega/dsh-remote/issues"
40
+ },
41
+ "homepage": "https://github.com/mrRisega/dsh-remote/tree/main/packages/dsh-remote-ui#readme",
25
42
  "license": "PolyForm-Noncommercial-1.0.0"
26
- }
43
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ "https://raw.githubusercontent.com/mrRisega/dsh-remote/main/image/phone-mirror.png",
3
+ "https://raw.githubusercontent.com/mrRisega/dsh-remote/main/image/phone-devices.png",
4
+ "https://raw.githubusercontent.com/mrRisega/dsh-remote/main/image/selfhost-settings.png"
5
+ ]