dsh-mesh-ui 0.0.8 → 0.0.11
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/lib/client.js +37 -4
- package/lib/index.js +2 -0
- package/package.json +5 -5
package/lib/client.js
CHANGED
|
@@ -678,7 +678,7 @@ body.light .dm-edge-label { stroke: rgba(255,255,255,.92); }
|
|
|
678
678
|
h('span', null, '⋯')
|
|
679
679
|
)
|
|
680
680
|
),
|
|
681
|
-
h('div', { className: 'dm-hint' }, '拓扑
|
|
681
|
+
h('div', { className: 'dm-hint' }, '拓扑 v21 · 内容 ' + Math.round(layout.W) + '×' + Math.round(layout.H) + 'px · 卡 ' + Math.round(layout.cardW) + '×' + Math.round(layout.cardH) + ' · 缩放 ' + Math.round(view.scale * 100) + '% · 滚轮缩放 / 拖拽平移')
|
|
682
682
|
)
|
|
683
683
|
}
|
|
684
684
|
|
|
@@ -1293,6 +1293,32 @@ function deviceLinkState(data, peer, lanMap) {
|
|
|
1293
1293
|
return v
|
|
1294
1294
|
}
|
|
1295
1295
|
|
|
1296
|
+
// 2026-11-10:设备状态与拓扑同口径 —— 任一链路可达即算在线(HTTP 探测偶发超时不再误判红点)
|
|
1297
|
+
var lanUpByDev = {}
|
|
1298
|
+
;(data.peers || []).forEach(function (p) {
|
|
1299
|
+
if (!isLanPeer(p)) return
|
|
1300
|
+
var tu = p.tunnel || {}
|
|
1301
|
+
lanUpByDev[peerDeviceKey(p.name)] = tu.probe ? tu.probe.up === true : Boolean(p.up)
|
|
1302
|
+
})
|
|
1303
|
+
function peerLinkState(peer) {
|
|
1304
|
+
var t = peer.tunnel || {}
|
|
1305
|
+
var httpUp = Boolean(peer.up)
|
|
1306
|
+
var tcpUp = t.probe ? t.probe.up === true : false
|
|
1307
|
+
var sk = sakuraTunnelOf(data, peerDeviceKey(peer.name))
|
|
1308
|
+
var sakuraUp = sk ? sk.online === true : null
|
|
1309
|
+
var lanUp = lanUpByDev[peerDeviceKey(peer.name)] === true
|
|
1310
|
+
return {
|
|
1311
|
+
httpUp: httpUp, tcpUp: tcpUp, sakuraUp: sakuraUp, lanUp: lanUp,
|
|
1312
|
+
up: httpUp || tcpUp || sakuraUp === true || lanUp
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
function linkStateText(ls) {
|
|
1316
|
+
return "公网 " + ((ls.httpUp || ls.tcpUp) ? "✅" : "❌")
|
|
1317
|
+
+ " / 樱花 " + (ls.sakuraUp == null ? "—" : (ls.sakuraUp ? "✅" : "❌"))
|
|
1318
|
+
+ (ls.lanUp ? " / LAN ✅" : "")
|
|
1319
|
+
+ (ls.httpUp ? "" : "(HTTP 超时,隧道" + (ls.tcpUp ? "通" : "断") + ")")
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1296
1322
|
var devices = [{
|
|
1297
1323
|
key: 'local',
|
|
1298
1324
|
name: nodeDisplay(data.nodeName) + '(本机)',
|
|
@@ -1310,11 +1336,12 @@ function deviceLinkState(data, peer, lanMap) {
|
|
|
1310
1336
|
]
|
|
1311
1337
|
}].concat(peers.map(function (peer) {
|
|
1312
1338
|
var t = peer.tunnel || {}
|
|
1339
|
+
var ls = peerLinkState(peer)
|
|
1313
1340
|
var hwp = peer.hardware || {}
|
|
1314
1341
|
return {
|
|
1315
1342
|
key: 'peer:' + peer.name,
|
|
1316
1343
|
name: nodeDisplay(peerDeviceKey(peer.name)),
|
|
1317
|
-
up:
|
|
1344
|
+
up: ls.up,
|
|
1318
1345
|
rows: [
|
|
1319
1346
|
['设备类型', formFactorOf(hwp)],
|
|
1320
1347
|
['操作系统', hwp.os || peer.os || '—'],
|
|
@@ -1324,7 +1351,8 @@ function deviceLinkState(data, peer, lanMap) {
|
|
|
1324
1351
|
['DSH 版本', dshVerOf(peer)],
|
|
1325
1352
|
['IP 类型', ipKindOf(peer)],
|
|
1326
1353
|
['端口号', t.port ? String(t.port) : '—'],
|
|
1327
|
-
['公网穿透类型', relayKindOf(peer)]
|
|
1354
|
+
['公网穿透类型', relayKindOf(peer)],
|
|
1355
|
+
['链路状态', linkStateText(ls)]
|
|
1328
1356
|
]
|
|
1329
1357
|
}
|
|
1330
1358
|
}))
|
|
@@ -1901,6 +1929,11 @@ body[data-ds-dark-theme] .dm-dg-fs-item.active { background:rgba(88,166,255,.28)
|
|
|
1901
1929
|
|
|
1902
1930
|
function loadSession() {
|
|
1903
1931
|
if (!selected || !selected.sessionId) return
|
|
1932
|
+
// 2026-11-10:本机任务(local)没有对端会话,不要发 peer call
|
|
1933
|
+
if (/^(local|self|localhost)$/i.test(String(selected.node || ''))) {
|
|
1934
|
+
flash('bad', '本机任务(local)没有对端会话;请在 DSH 侧栏查看本机会话')
|
|
1935
|
+
return
|
|
1936
|
+
}
|
|
1904
1937
|
setSessionLoading(true)
|
|
1905
1938
|
dgFetch(DG_API_SESSION + '?node=' + encodeURIComponent(selected.node) + '&sessionId=' + encodeURIComponent(selected.sessionId) + '&limit=60')
|
|
1906
1939
|
.then(function (json) {
|
|
@@ -2166,7 +2199,7 @@ body[data-ds-dark-theme] .dm-dg-fs-item.active { background:rgba(88,166,255,.28)
|
|
|
2166
2199
|
'对端会话',
|
|
2167
2200
|
h('span', { className: 'dm-dg-sub' }, session ? ('轮次 ' + (session.totalMessages || sessionMessages.length) + ' · 帧 ' + (session.frameCount || '—') + ' · ' + Math.round((session.bytes || 0) / 1024) + ' KB') : '只读'),
|
|
2168
2201
|
h('span', { className: 'dm-dg-spacer' }),
|
|
2169
|
-
h('button', { type: 'button', className: 'dm-dg-btn primary', onClick: loadSession, disabled: sessionLoading || !selected.sessionId },
|
|
2202
|
+
h('button', { type: 'button', className: 'dm-dg-btn primary', onClick: loadSession, disabled: sessionLoading || !selected.sessionId || /^(local|self|localhost)$/i.test(String(selected.node || '')) },
|
|
2170
2203
|
sessionLoading ? h('span', { className: 'dm-dg-loading' }, h('span', { className: 'dm-dg-spin' }), '加载中') : (session ? '重新加载' : '加载会话'))
|
|
2171
2204
|
),
|
|
2172
2205
|
h('div', { className: 'dm-dg-sec-body' },
|
package/lib/index.js
CHANGED
|
@@ -176,6 +176,8 @@ export function apply(ctx) {
|
|
|
176
176
|
}),
|
|
177
177
|
readonlyRoute('/api/dsh-mesh/session', async (url) => {
|
|
178
178
|
const node = String(url.searchParams.get('node') || '')
|
|
179
|
+
// 2026-11-10:本机任务(node=local)没有对端会话,直接给出明确错误,避免 peer call --to local 报 unknown peer
|
|
180
|
+
if (/^(local|self|localhost)$/i.test(node)) return { ok: false, code: "E_LOCAL_NODE", error: "本机任务(local)没有对端会话;请在 DSH 侧栏查看本机会话" }
|
|
179
181
|
const sessionId = String(url.searchParams.get('sessionId') || '')
|
|
180
182
|
const limit = Number(url.searchParams.get('limit')) || 40
|
|
181
183
|
if (!node || !sessionId) return { ok: false, error: 'node and sessionId required' }
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mesh-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "DSH settings-page panel for dsh-mesh: AI network topology, peer health, and delegation panel. Read-only; data is collected from the local mesh CLI.",
|
|
5
5
|
"icon": "icon.svg",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": "^22.19.0 || >=24.0.0"
|
|
8
|
+
"node": "^22.19.0 || >=24.0.0",
|
|
9
|
+
"dsh": ">=0.2.0-rc.2 <0.3.0"
|
|
9
10
|
},
|
|
10
11
|
"main": "lib/index.js",
|
|
11
12
|
"exports": {
|
|
@@ -14,9 +15,7 @@
|
|
|
14
15
|
"./package.json": "./package.json"
|
|
15
16
|
},
|
|
16
17
|
"dsh": {
|
|
17
|
-
"
|
|
18
|
-
"dsh": ">=0.2.0-rc.2"
|
|
19
|
-
},
|
|
18
|
+
"manifestVersion": 1,
|
|
20
19
|
"bundle": {
|
|
21
20
|
"patch": "./cordis.patch.yml"
|
|
22
21
|
},
|
|
@@ -29,6 +28,7 @@
|
|
|
29
28
|
}
|
|
30
29
|
},
|
|
31
30
|
"peerDependencies": {
|
|
31
|
+
"@deepseek-ai/dsh": ">=0.2.0-rc.2 <0.3.0",
|
|
32
32
|
"react": "^18.2.0",
|
|
33
33
|
"react-dom": "^18.2.0"
|
|
34
34
|
},
|