dsh-crossterm 0.8.7 → 0.8.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # dsh-crossterm 变更记录
2
2
 
3
+ ## 0.8.8 — 2026-10-19
4
+
5
+ ### 「维护者」一栏只给维护端看
6
+
7
+ - **问题**:0.8.5 加的「维护者」行任何设备装上插件都会显示负责人是谁,而这是维护端信息,
8
+ 别的机器不需要看到。
9
+ - **判断规则**:新增导出纯函数 `maintainerVisible(term, doc)` —— 本机 `nodeId` 必须命中
10
+ `MAINTAINERS.md` 机器可读注释里的 `current` 或 `assistant` 条目(负责人与助手同机时都算
11
+ 「本机授权端」);配置 `maintainerDevices`(`bus.js` DEFAULTS 新增,默认 `[]`)可额外放行设备。
12
+ - **接口**:`GET /crossterm/api/about` 的 `maintainers` 增加 `visible`(布尔)与 `me`(本机 nodeId),
13
+ 客户端据此决定渲不渲染该行;负责人换机器只改 `MAINTAINERS.md` 的 `current.nodeId`,不用改代码。
14
+ - **测试**:`F:\dsh\001X\crossterm-work\probe-maintainer-visible.mjs` 15 项全过
15
+ (维护端可见、其他设备不可见、助手同机可见、显式授权可见、换机后本机隐藏、无文档/无 nodeId/cfg 为 null 等边界)。
16
+
3
17
  ## 0.8.7 — 2026-10-19
4
18
 
5
19
  ### 修 0.8.6 的回归:云端设备列表整个消失
package/README.md CHANGED
@@ -28,19 +28,23 @@ A 终端看不到 B 终端里有哪个会话、在干什么,也没法把一条
28
28
  > `locatePkgJson()` 对子路径行返回 undefined),而插件页顶部标题与这一行共用同一份 `locale/zh.json` 的 meta,
29
29
  > 所以它单独做总开关,标题带「(总开关)」;卡片头用 `shortTitle` 显示短名「跨端互通」。
30
30
 
31
- **本版更新(0.8.7)**
31
+ **本版更新(0.8.8)**
32
32
 
33
- - **修 0.8.6 的回归**:0.8.6 装上后卡片「云端设备」整块消失,接口报
34
- `layout is not defined`(路由里把 `layout` 声明在 `try` 块内、块外又用了它)。
35
- 0.8.7 已修;本来就还没升 0.8.6 的设备可以直接装 0.8.7。
36
- - **合并逻辑变成可测的纯函数**:`mergeDevices({ old, fresh, selfId, ownerDevice })` 负责
37
- 「老总线镜像 + 新布局心跳」的合并、排除本机、补管理员/成员角色、按心跳倒序,
38
- 路由不再自己拼装,配套 20 项单测。
39
- - **离线时间排序口径统一**:`annotateDevices()` 把 `at → lastSeen → updatedAt` 归一成毫秒,
40
- 列表按它倒序,不会再把 ISO 字符串和毫秒时间戳混着比。
41
- - 纯展示与拼装修复,装上重启即可,不用改配置。
33
+ - **「维护者」一栏只给维护端看**:以前任何设备装上插件都能看到负责人是谁;现在只在维护端显示 ——
34
+ 本机 `nodeId` 必须出现在 `MAINTAINERS.md` 的负责人/助手条目里(两者在同一台机器上时都算),
35
+ 或用配置 `maintainerDevices` 显式放行。其他设备上这行直接不渲染。
36
+ - **换机器只改一个字段**:负责人换机器时,把 `MAINTAINERS.md` 里 `current.nodeId` 改成新机器,
37
+ 旧机器下次刷新卡片自动隐藏,不用改代码。
38
+ - 纯展示改动,装上重启即可,不用改配置。
42
39
 
43
- **上一版(0.8.6)**
40
+ **上一版(0.8.7)**
41
+
42
+ - **修 0.8.6 的回归**:0.8.6 装上后卡片「云端设备」整块消失(接口报 `layout is not defined`);
43
+ 0.8.7 已修,没升 0.8.6 的设备可直接装 0.8.7。
44
+ - **合并逻辑变成可测的纯函数**:`mergeDevices({ old, fresh, selfId, ownerDevice })`,配套 20 项单测。
45
+ - **离线时间排序口径统一**:`at → lastSeen → updatedAt` 先归一毫秒再排。
46
+
47
+ **更早(0.8.6 / 0.8.5 / 0.8.2 / 0.8.0)**
44
48
 
45
49
  - **云端设备只列「别人」**:卡片里那行不再显示本机(自己已经在「当前终端」一栏),
46
50
  只列同一账号下的其他设备。
@@ -50,8 +54,6 @@ A 终端看不到 B 终端里有哪个会话、在干什么,也没法把一条
50
54
  离线设备一律「未知」;现在按 `updatedAt → at → lastSeen` 依次取。
51
55
  - `term_list` 的云端行也带角色。
52
56
 
53
- **更早(0.8.5 / 0.8.2 / 0.8.0)**
54
-
55
57
  - 0.8.5:负责人留痕 `MAINTAINERS.md`、运行日志可轮转(5 MB 压 `logs/archive/` 留 20 份)、
56
58
  卡片「维护者」行与「运行日志」按钮、`GET /crossterm/api/logs`。
57
59
  - 0.8.2:死信按 20s/1m/5m/15m/1h 退避,8 次后进 `dead/`;收件人写设备名会回退「最近活跃会话」;
package/client/client.js CHANGED
@@ -482,7 +482,7 @@ window.__ModuleLoader__.load({
482
482
  label: "当前终端",
483
483
  value: status ? `${status.node}(${status.nodeId})· ${status.hostname}` : "",
484
484
  }),
485
- about && about.maintainers
485
+ about && about.maintainers && about.maintainers.visible === true
486
486
  ? h(FriendlyRow, {
487
487
  label: "维护者",
488
488
  value: maintainersText(about),
package/lib/bus.js CHANGED
@@ -23,7 +23,7 @@ import path from 'node:path'
23
23
  import crypto from 'node:crypto'
24
24
  import { rotateIfNeeded } from './logs.js'
25
25
 
26
- export const VERSION = '0.8.7'
26
+ export const VERSION = '0.8.8'
27
27
 
28
28
  /** DSH 的家目录:与宿主其它状态(sessions / profiles)同一个根,多终端天然共享 */
29
29
  export function dshHome() {
@@ -79,6 +79,9 @@ const DEFAULTS = {
79
79
  backupSessionsPerRun: 20,
80
80
  backupAttachmentsPerRun: 20,
81
81
  attachmentBackupEnabled: true,
82
+ // 卡片「维护者」一栏只在维护端显示:默认按 MAINTAINERS.md 里的 nodeId 判断,
83
+ // 这里可以额外放行别的设备(例如用户授权过的本机另装环境)。
84
+ maintainerDevices: [],
82
85
  baiduAppFile: '',
83
86
  baiduAuthFile: '',
84
87
  cloudStateFile: '',
package/lib/web.js CHANGED
@@ -506,7 +506,28 @@ function readMaintainers() {
506
506
  return readMaintainersDoc(ROOT)
507
507
  }
508
508
 
509
- function aboutOf() {
509
+ /**
510
+ * 「维护者」只给维护端看:本机 nodeId 必须出现在 MAINTAINERS.md 的
511
+ * 负责人/助手条目里,或用配置 `maintainerDevices` 额外授权;其他设备一律不给这行。
512
+ */
513
+ export function maintainerVisible(term, doc) {
514
+ if (!doc) return false
515
+ const self = String((term && term.nodeId) || '')
516
+ if (!self) return false
517
+ const allow = new Set()
518
+ const add = (item) => {
519
+ if (item && item.nodeId) allow.add(String(item.nodeId))
520
+ }
521
+ add(doc.current)
522
+ add(doc.assistant)
523
+ try {
524
+ const extra = term && term.cfg && Array.isArray(term.cfg.maintainerDevices) ? term.cfg.maintainerDevices : []
525
+ for (const item of extra) allow.add(String(item))
526
+ } catch { /* ignore */ }
527
+ return allow.has(self)
528
+ }
529
+
530
+ function aboutOf(term) {
510
531
  if (aboutCache && aboutCache.version === VERSION) return aboutCache
511
532
  let meta = {}
512
533
  try {
@@ -524,6 +545,7 @@ function aboutOf() {
524
545
  description: doc.description || '',
525
546
  }
526
547
  })
548
+ const maintainers = readMaintainers()
527
549
  aboutCache = {
528
550
  name: PKG,
529
551
  version: VERSION,
@@ -532,7 +554,9 @@ function aboutOf() {
532
554
  shortTitle: meta.shortTitle || meta.title || PKG,
533
555
  description: meta.description || '',
534
556
  components,
535
- maintainers: readMaintainers(),
557
+ maintainers: maintainers
558
+ ? { ...maintainers, visible: maintainerVisible(term, maintainers), me: String((term && term.nodeId) || '') }
559
+ : null,
536
560
  changelog: readChangelog(),
537
561
  }
538
562
  return aboutCache
@@ -578,7 +602,7 @@ export function registerWeb(ctx, term, log) {
578
602
  path: '/crossterm/api/about',
579
603
  handler: (req, res) => {
580
604
  try {
581
- json(res, 200, { ok: true, ...aboutOf() })
605
+ json(res, 200, { ok: true, ...aboutOf(term) })
582
606
  } catch (error) {
583
607
  json(res, 200, { ok: false, message: String((error && error.message) || error) })
584
608
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-crossterm",
3
- "version": "0.8.7",
3
+ "version": "0.8.8",
4
4
  "description": "跨端互通:同一 DSH 账号下的会话、终端、设备之间互通 —— 特征码链、内联邮件、云端中转站与自动备份",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",