@mrrisega/dsh-remote 0.6.0-beta.0 → 0.6.0-beta.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrrisega/dsh-remote",
|
|
3
|
-
"version": "0.6.0-beta.
|
|
3
|
+
"version": "0.6.0-beta.1",
|
|
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",
|
|
@@ -146,9 +146,71 @@ window.__ModuleLoader__.load({
|
|
|
146
146
|
".dru-dev-sub{font-size:11px;color:#8c959f;margin-top:3px}",
|
|
147
147
|
".dru-dev-tag{font-size:10.5px;color:#8c959f;border:1px solid #d0d7de;border-radius:999px;padding:0 7px;flex:none;white-space:nowrap}",
|
|
148
148
|
".dru-dev-tag-off{color:#cf222e;border-color:#ffb3b6;background:#fff0f1}",
|
|
149
|
+
// 左下角「远程访问」快捷小手机图标(安装后常驻;首次点击前带红点)
|
|
150
|
+
".dru-fab{position:fixed;left:18px;bottom:18px;z-index:2147482100;width:46px;height:46px;border-radius:50%;background:#0969da;color:#fff;border:none;display:flex;align-items:center;justify-content:center;font-size:22px;line-height:1;box-shadow:0 6px 18px rgba(0,0,0,.28);cursor:pointer;font-family:inherit;padding:0}",
|
|
151
|
+
".dru-fab:hover{background:#0860bd}",
|
|
152
|
+
".dru-fab-dot{position:absolute;top:2px;right:2px;width:9px;height:9px;border-radius:50%;background:#e5484d;box-shadow:0 0 0 2px #fff;pointer-events:none}",
|
|
149
153
|
].join("\n");
|
|
150
154
|
document.head.appendChild(styleEl);
|
|
151
155
|
|
|
156
|
+
// ── 左下角「远程访问」快捷小手机图标 ──
|
|
157
|
+
// 常驻于左下角:点击打开 设置页 → 「远程访问」栏目;首次点击前显示小红点(localStorage 一次)。
|
|
158
|
+
var FAB_SEEN_KEY = "dsh-remote-fab-seen";
|
|
159
|
+
function clickTextNav(text) {
|
|
160
|
+
try {
|
|
161
|
+
var nodes = document.querySelectorAll('button, [role="tab"], [class*="navCell"], [class*="nav"], [class*="sidebar"] a, a');
|
|
162
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
163
|
+
var el = nodes[i];
|
|
164
|
+
var t = (el.textContent || "").trim();
|
|
165
|
+
if (t === text || t.indexOf(text) === 0) {
|
|
166
|
+
try { el.click(); return true; } catch (e) { /* 尝试下一个 */ }
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} catch (e) { /* 忽略 */ }
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
function openRemoteSettings() {
|
|
173
|
+
if (clickTextNav("远程访问")) return; // 已在栏目内/可直接点到
|
|
174
|
+
if (clickTextNav("设置")) { /* 进入设置页后再轮询远程访问栏目 */ }
|
|
175
|
+
var tries = 0;
|
|
176
|
+
var iv = setInterval(function () {
|
|
177
|
+
if (clickTextNav("远程访问")) { clearInterval(iv); return; }
|
|
178
|
+
if (++tries > 40) clearInterval(iv);
|
|
179
|
+
}, 150);
|
|
180
|
+
if (typeof iv.unref === "function") iv.unref();
|
|
181
|
+
}
|
|
182
|
+
function ensureRemoteFab() {
|
|
183
|
+
try {
|
|
184
|
+
if (document.getElementById("dru-remote-fab")) return;
|
|
185
|
+
if (!document.body) { setTimeout(ensureRemoteFab, 300); return; }
|
|
186
|
+
var fab = document.createElement("button");
|
|
187
|
+
fab.id = "dru-remote-fab";
|
|
188
|
+
fab.className = "dru-fab";
|
|
189
|
+
fab.type = "button";
|
|
190
|
+
fab.setAttribute("aria-label", "远程访问");
|
|
191
|
+
fab.textContent = "📱";
|
|
192
|
+
var seen = false;
|
|
193
|
+
try { seen = !!localStorage.getItem(FAB_SEEN_KEY); } catch (e) {}
|
|
194
|
+
if (!seen) {
|
|
195
|
+
var dot = document.createElement("span");
|
|
196
|
+
dot.className = "dru-fab-dot";
|
|
197
|
+
fab.appendChild(dot);
|
|
198
|
+
}
|
|
199
|
+
fab.addEventListener("click", function () {
|
|
200
|
+
try { localStorage.setItem(FAB_SEEN_KEY, "1"); } catch (e) {}
|
|
201
|
+
var d = fab.querySelector(".dru-fab-dot");
|
|
202
|
+
if (d) d.remove();
|
|
203
|
+
openRemoteSettings();
|
|
204
|
+
});
|
|
205
|
+
document.body.appendChild(fab);
|
|
206
|
+
} catch (e) { /* 非关键 */ }
|
|
207
|
+
}
|
|
208
|
+
if (document.readyState === "loading") {
|
|
209
|
+
document.addEventListener("DOMContentLoaded", ensureRemoteFab);
|
|
210
|
+
} else {
|
|
211
|
+
setTimeout(ensureRemoteFab, 600);
|
|
212
|
+
}
|
|
213
|
+
|
|
152
214
|
// ── 首次安装引导小红点(设置页「远程访问」栏目,localStorage 控制) ────
|
|
153
215
|
// 无 dsh-remote-seen-dot key 视为首次:在设置页导航栏目右上角显示 CSS 圆点;
|
|
154
216
|
// 点击栏目/红点后写入 key(之后不再显示),重启 DSH Web 不复发。
|
|
@@ -921,6 +983,11 @@ window.__ModuleLoader__.load({
|
|
|
921
983
|
/** 创建(或刷新)一次性访问密钥:GET /dsh-remote/access-key(node 半转发企业端 /api/auth-key)。 */
|
|
922
984
|
function loadAccessKey() {
|
|
923
985
|
if (akeyBusy) return;
|
|
986
|
+
// 登录前不请求企业端(避免 401/404 噪音);由账号登录成功后触发
|
|
987
|
+
if (!(st && st.config && st.config.phone)) {
|
|
988
|
+
setAkeyMsg(null);
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
924
991
|
setAkeyBusy(true);
|
|
925
992
|
api("/dsh-remote/access-key").then(function (b) {
|
|
926
993
|
if (!b || !b.ok) {
|
|
@@ -1266,8 +1333,12 @@ window.__ModuleLoader__.load({
|
|
|
1266
1333
|
var expMs = akey ? toMs(akey.expires_at) : 0;
|
|
1267
1334
|
var remainMs = expMs ? expMs - nowTick : 0;
|
|
1268
1335
|
var loggedInSaaS = !!(st && st.config && st.config.phone);
|
|
1269
|
-
var statusTxt = st === null
|
|
1270
|
-
|
|
1336
|
+
var statusTxt = st === null
|
|
1337
|
+
? "查询中…"
|
|
1338
|
+
: !loggedInSaaS
|
|
1339
|
+
? "请先登录(下方账号卡片)后启用远程访问"
|
|
1340
|
+
: serviceRunning ? "已连接(可远程访问)" : "等待设备连接";
|
|
1341
|
+
var dotCls = "dru-dot " + (loggedInSaaS && serviceRunning ? "dru-dot-on" : "dru-dot-off");
|
|
1271
1342
|
return card("📱 远程访问", [
|
|
1272
1343
|
h("div", { className: "dru-status-line" },
|
|
1273
1344
|
h("span", { className: dotCls }),
|
|
@@ -1394,7 +1465,8 @@ window.__ModuleLoader__.load({
|
|
|
1394
1465
|
// 云端 tab:📱 远程访问(一次性扫码访问 + 已授权设备)+ 账号(手机号登录,官方托管)
|
|
1395
1466
|
!isLocal ? h("div", null,
|
|
1396
1467
|
renderAccessCard(),
|
|
1397
|
-
|
|
1468
|
+
// 已授权设备:仅登录后展示(登录前不显示,避免空列表/误导)
|
|
1469
|
+
loggedIn && st.config.phone ? renderDevicesCard() : null,
|
|
1398
1470
|
card("🔑 账号",
|
|
1399
1471
|
st === null
|
|
1400
1472
|
? h("div", { className: "dru-hint" }, "正在读取远控状态…")
|
|
@@ -946,7 +946,7 @@ const PLUGIN_ID = "dsh-remote-web";
|
|
|
946
946
|
const PLUGIN_LEGACY_IDS = ["dsh-remote-ui"];
|
|
947
947
|
const PLUGIN_ALL_IDS = [PLUGIN_ID, ...PLUGIN_LEGACY_IDS];
|
|
948
948
|
/** 插件自身发布版本(与 dsh-remote 根包同步递增)。 */
|
|
949
|
-
const PLUGIN_VERSION = "0.6.0-beta.
|
|
949
|
+
const PLUGIN_VERSION = "0.6.0-beta.1";
|
|
950
950
|
const UPDATE_LOG = ".dsh-update.log";
|
|
951
951
|
const UPDATE_MARKER = ".dsh-update-running";
|
|
952
952
|
|
|
@@ -58,7 +58,7 @@ test("反馈代理:附加设备身份/手机号,透传 thread_token", async
|
|
|
58
58
|
assert.equal(echo.url, "/api/feedback");
|
|
59
59
|
assert.equal(echo.headers["x-dsh-device"], "dev-testproxy123");
|
|
60
60
|
assert.equal(echo.headers["x-dsh-phone"], "13800000000");
|
|
61
|
-
assert.
|
|
61
|
+
assert.match(echo.headers["x-dsh-client"], /^dsh-remote-web\/\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/, `x-dsh-client 应带插件名与版本,实际 ${echo.headers["x-dsh-client"]}`);
|
|
62
62
|
assert.equal(echo.headers.authorization, "Bearer thread-token-abc");
|
|
63
63
|
assert.equal(echo.body.category, "bug");
|
|
64
64
|
|
|
@@ -55,7 +55,7 @@ test("self 路由:版本可见 + 运行环境状态(无 npx 环境时不谎
|
|
|
55
55
|
try {
|
|
56
56
|
const self = await (await fetch(`${base}/dsh-remote/self`)).json();
|
|
57
57
|
assert.equal(self.ok, true);
|
|
58
|
-
assert.match(self.version, /^\d+\.\d+\.\d
|
|
58
|
+
assert.match(self.version, /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/, `version 应为 semver(含预发布),实际 ${self.version}`);
|
|
59
59
|
assert.equal(self.runtimeReady, false, "temp 目录没有 dsh-setup.mjs → runtimeReady=false");
|
|
60
60
|
assert.equal(self.relayDir, tempDir);
|
|
61
61
|
} finally {
|