dsh-crossterm 0.6.2 → 0.7.0

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,23 @@
1
1
  # dsh-crossterm 变更记录
2
2
 
3
+ ## 0.7.0 — 2026-10-19
4
+
5
+ ### 入口行升格为「总开关」,排到组件列表第一位
6
+ - 用户要求(paraphrased):把入口那一行放到第一个,开关做成和插件开关一样的**总开关**,并标注清楚。
7
+ - `cordis.patch.yml` 顺序变化:`crossterm-ui`(裸包名 `dsh-crossterm`,`config.part: ui`)从列表末尾
8
+ 移到**第一位**,其后依次是 session / terminal / device / account。五行指向同一个包,顺序只影响展示。
9
+ - **总开关是真开关**,不是只关卡片(`lib/index.js` 的 `apply()`):
10
+ - `part === 'ui'` 时 `root.provide('crossterm', { master: true, part, since })`;
11
+ - 其余四个组件改为 `root.inject(['agents', 'crossterm'], ...)` —— **总开关关掉时服务不存在,
12
+ 这四个回调根本不会执行**,工具、心跳、云同步、云端中转站、会话备份一起停;
13
+ - 总开关开着时,四个组件之间仍可各自单独开关;
14
+ - 总开关 3 秒内没出现时打一行 `console.warn`(`总开关(入口组件)未启用,组件「X」已跳过挂载`)方便排查;
15
+ - 用 cordis 服务注入而不是「读配置 / 看加载顺序」,所以谁先加载都不影响结果。
16
+ - 标注清楚:`locale/zh.json` 的 `meta.title` 改为 **跨端互通(总开关)**,`meta.description` 写明
17
+ 「关掉这一项,下面四个组件全部停用……开着它时四个组件可各自单独开关」;
18
+ 新增 `meta.shortTitle = 跨端互通`,配置卡片标题用短名(`GET /crossterm/api/about` 多返回一个 `shortTitle`)。
19
+ - 探针 `probe-about.mjs` 改为断言 `title === '跨端互通(总开关)'` 且 `shortTitle === '跨端互通'`。
20
+
3
21
  ## 0.6.2 — 2026-10-19
4
22
 
5
23
  ### 插件页:插件名/简介/组件表/更新日志
package/README.md CHANGED
@@ -12,28 +12,28 @@ A 终端看不到 B 终端里有哪个会话、在干什么,也没法把一条
12
12
 
13
13
  ## 零、简介与本版更新(每次发版重写这一节)
14
14
 
15
- **插件名称**:`dsh-crossterm`(插件页显示 **跨端互通**)| **插件简介**:同一 DSH 账号下的会话、终端、设备之间互通 —— 特征码链、内联邮件、云端中转站与自动备份。
15
+ **插件名称**:`dsh-crossterm`(插件页显示 **跨端互通(总开关)**)| **插件简介**:同一 DSH 账号下的会话、终端、设备之间互通 —— 特征码链、内联邮件、云端中转站与自动备份。
16
16
 
17
- **四个组件(插件页里就是这四个开关,名称与简介来自各自的 manifest)**
17
+ **组件列表(插件页第一个是总开关,后面四个是业务组件,名称与简介来自各自的 manifest)**
18
18
 
19
- | 组件名称 | 组件简介 | 工具 |
20
- |---|---|---|
21
- | 跨会话 | 同一终端里的多个会话之间互通:特征码链、内联邮件、收件箱 | `term_link` `term_unlink` `term_broadcast` `term_inbox` `term_config` |
22
- | 跨终端 | 同一台机器上的多个 DSH 终端/进程之间互发邮件与文件 | `term_whoami` `term_list` `term_send` `term_send_files` |
23
- | 跨设备 | 经云端总线,在多台机器的 DSH 之间互发邮件与文件 | `term_cloud` |
24
- | 跨账号 | 预留位:后续用于跨账号互通,当前不挂工具 | — |
19
+ | 顺序 | 组件名称 | 作用 | 工具 |
20
+ |---|---|---|---|
21
+ | ① | 跨端互通(总开关) | 插件总开关:关掉它,下面四个组件全部停用(工具、心跳、云同步、中转站、备份一起停);开着时四个组件可各自单独开关。裸包名行,承载插件标题/简介与配置卡片,不挂工具 | — |
22
+ | ② | 跨会话 | 同一终端里的多个会话之间互通:特征码链、内联邮件、收件箱 | `term_link` `term_unlink` `term_broadcast` `term_inbox` `term_config` |
23
+ | ③ | 跨终端 | 同一台机器上的多个 DSH 终端/进程之间互发邮件与文件 | `term_whoami` `term_list` `term_send` `term_send_files` |
24
+ | ④ | 跨设备 | 经云端总线,在多台机器的 DSH 之间互发邮件与文件 | `term_cloud` |
25
+ | ⑤ | 跨账号 | 预留位:后续用于跨账号互通,当前不挂工具 | — |
25
26
 
26
- > 插件页里还会多出一行 **跨端互通**(组件列表最后一行):它是「入口行」,裸包名加载浏览器半端,
27
- > 承载插件标题与配置卡片,不挂任何工具。浏览器 client 半端只认裸包名行,所以这一行没法省。
27
+ > 总开关为什么必须用裸包名:浏览器 client 半端只对裸包名行生效(`dsh-client-modules` 的
28
+ > `locatePkgJson()` 对子路径行返回 undefined),而插件页顶部标题与这一行共用同一份 `locale/zh.json` 的 meta,
29
+ > 所以它单独做总开关,标题带「(总开关)」;卡片头用 `shortTitle` 显示短名「跨端互通」。
28
30
 
29
- **本版更新(0.6.2)**
31
+ **本版更新(0.7.0)**
30
32
 
31
- - **插件页终于像个插件了**:插件改名 **跨端互通**(原来叫「跨会话」,看起来像只管会话),
32
- 并写上了插件级简介;四个业务组件名保持不变。
33
- - 配置卡片里新增:**插件简介**、**包含的组件(名称 + 简介两列表格)**、底部可折叠 **更新日志**
34
- (直接读包内 `CHANGELOG.md`,展开就能看最近三版改了什么)。
35
- - 数据来自新接口 `GET /crossterm/api/about`(组件名与简介读 `parts/*.manifest.json`,与组件行同源)。
36
- - 上一版(0.6.1)的内容仍在:旧布局缓存不再挡住云端规则文档与 `inbox/_说明.md`。
33
+ - **第一个组件变成总开关**:排到列表最前,标注「跨端互通(总开关)」,说明写明关掉它会停掉下面四个组件。
34
+ - 它不再是「只关卡片的入口行」:现在用 cordis 服务注入实现 —— ui 行 `provide('crossterm')`,
35
+ 其余四行 `inject` 它;**关掉总开关,那四个组件连回调都不会执行**,工具/心跳/云同步/中转站/备份一起停。
36
+ - 四个业务组件仍可各自单独开关(总开关开着时)。
37
37
 
38
38
  ## 一、安装与卸载
39
39
 
package/client/client.js CHANGED
@@ -373,7 +373,7 @@ window.__ModuleLoader__.load({
373
373
  h(
374
374
  "div",
375
375
  null,
376
- h("div", { style: S.title }, `${(about && about.title) || "跨端互通"} ${version}`),
376
+ h("div", { style: S.title }, `${(about && (about.shortTitle || about.title)) || "跨端互通"} ${version}`),
377
377
  h("div", { style: S.sub }, subtitle),
378
378
  ),
379
379
  // h("span", { style: S.chevron }, open ? "\u2303" : "\u2304"),
package/cordis.patch.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  # ============================================================================
2
- # dsh-crossterm —— DSH bundle patch(host-only 插件)
2
+ # dsh-crossterm —— DSH bundle patch
3
3
  # ============================================================================
4
4
  # 安装(本地目录,对每个要互通的 profile 各装一次):
5
5
  # dsh plugin --profile desktop add link:F:\dsh\001X\dsh-crossterm
@@ -7,30 +7,41 @@
7
7
  # 卸载:
8
8
  # dsh plugin --profile desktop remove dsh-crossterm
9
9
  #
10
- # 每个 insert 行在 DSH「插件 → dsh-crossterm → 包含的组件」里是一行组件,可单独开关。
11
- # 五行指向同一个包,只是走不同子路径:
10
+ # 每个 insert 行在 DSH「插件 → 跨端互通 → 包含的组件」里是一行组件,可单独开关。
11
+ # 五行指向同一个包,只是走不同子路径 / 不同 config.part:
12
12
  #
13
- # dsh-crossterm 入口:插件页配置卡片(浏览器半端)+ 全插件简介/更新日志,
14
- # 不挂任何工具(config.part: ui)
15
- # dsh-crossterm/parts/session 跨会话:term_link / term_unlink / term_broadcast / term_inbox / term_config
16
- # dsh-crossterm/parts/terminal 跨终端:term_whoami / term_list / term_send / term_send_files
17
- # dsh-crossterm/parts/device 跨设备:term_cloud(云端总线同步)
18
- # dsh-crossterm/parts/account 跨账号:预留占位,暂不挂工具
13
+ # ① dsh-crossterm 总开关(入口):提供 crossterm 服务,插件页标题/简介/配置卡片,
14
+ # 不挂任何工具(config.part: ui)。
15
+ # 关掉它 → 服务消失 → 下面四个组件全部停用
16
+ # (工具、心跳、云同步、中转站、会话备份一起停)。
17
+ # ② dsh-crossterm/parts/session 跨会话:term_link / term_unlink / term_broadcast / term_inbox / term_config
18
+ # ③ dsh-crossterm/parts/terminal 跨终端:term_whoami / term_list / term_send / term_send_files
19
+ # ④ dsh-crossterm/parts/device 跨设备:term_cloud(云端总线同步)
20
+ # ⑤ dsh-crossterm/parts/account 跨账号:预留占位,暂不挂工具
19
21
  #
20
22
  # 组件名来自 package.json 的 exports 映射:
21
23
  # "./parts/session/package.json" -> "./parts/session.manifest.json"
22
24
  # 每个组件显示自己的中文名,实际加载的仍是 lib/index.js,靠 config.part 决定挂哪组工具。
23
25
  #
24
- # 为什么入口行放在最后:浏览器的 client 半端只对「裸包名」行生效(dsh-client-modules 的
25
- # locatePkgJson 对子路径行直接返回 undefined),而插件页顶部标题与裸包名行共用同一份
26
- # locale/zh.json 的 meta —— 插件叫「跨端互通」、四个业务组件叫跨会话/跨终端/跨设备/跨账号,
27
- # 只能让裸包名行单独做入口,且排在组件列表末尾,四个组件仍是列表里的前四行。
26
+ # 为什么总开关必须用「裸包名」:浏览器的 client 半端只对裸包名行生效
27
+ # (dsh-client-modules 的 locatePkgJson 对子路径行直接返回 undefined),而插件页顶部标题
28
+ # 与裸包名行共用同一份 locale/zh.json 的 meta —— 所以裸包名行单独做总开关,
29
+ # 标题写「跨端互通(总开关)」,四个业务组件排在它后面、名字仍是跨会话/跨终端/跨设备/跨账号。
30
+ #
31
+ # 总开关是「服务注入」实现的:ui 行 root.provide('crossterm'),其余四行 root.inject 它。
32
+ # 谁先加载不影响结果(cordis 的 inject 会等服务出现),顺序只为让列表好看。
28
33
  #
29
34
  # 五个组件在同一 DSH 进程里共用一份总线实例:心跳只起一次,云同步只在 device 组件启用
30
35
  # 且 config.json 里 cloudEnabled=true 时才跑。安装/改动后需重启对应的 DSH 进程。
31
36
  # ============================================================================
32
37
 
33
38
  - insert:
39
+ - id: crossterm-ui
40
+ # 总开关(入口):裸包名,提供 crossterm 服务 + 浏览器半端的配置卡片 + 插件页标题/简介。
41
+ # 关掉这一行等于整插件停用;它自己不挂工具。
42
+ name: dsh-crossterm
43
+ config:
44
+ part: ui
34
45
  - id: crossterm-session
35
46
  name: dsh-crossterm/parts/session
36
47
  config:
@@ -47,9 +58,3 @@
47
58
  name: dsh-crossterm/parts/account
48
59
  config:
49
60
  part: account
50
- - id: crossterm-ui
51
- # 裸包名:浏览器 client 半端只认这一行,插件页配置卡片挂在这里。
52
- # 也是插件页顶部标题/简介的来源(locale/zh.json 的 meta)。
53
- name: dsh-crossterm
54
- config:
55
- part: ui
package/lib/bus.js CHANGED
@@ -22,7 +22,7 @@ import os from 'node:os'
22
22
  import path from 'node:path'
23
23
  import crypto from 'node:crypto'
24
24
 
25
- export const VERSION = '0.6.2'
25
+ export const VERSION = '0.7.0'
26
26
 
27
27
  /** DSH 的家目录:与宿主其它状态(sessions / profiles)同一个根,多终端天然共享 */
28
28
  export function dshHome() {
package/lib/index.js CHANGED
@@ -1859,7 +1859,24 @@ export default {
1859
1859
  name: PLUGIN,
1860
1860
  apply(root, config) {
1861
1861
  const part = normalizePart(config?.part)
1862
- root.inject(['agents'], (ctx) => {
1862
+ // 「入口」这一行就是总开关:它提供 crossterm 服务,其余四个组件都 inject 它。
1863
+ // 关掉这一行 → 服务不存在 → 另外四个组件的 inject 回调根本不会执行,
1864
+ // 工具、心跳、云同步、中转站、会话备份一起停(不是只关卡片)。
1865
+ // 反过来,只要总开关开着,四个组件各自还能单独关。
1866
+ const isMaster = part === 'ui'
1867
+ if (isMaster) {
1868
+ root.provide('crossterm', { master: true, part, since: Date.now() })
1869
+ } else {
1870
+ const timer = setTimeout(() => {
1871
+ let alive = true
1872
+ try {
1873
+ alive = Boolean(root.get?.('crossterm'))
1874
+ } catch { alive = true }
1875
+ if (!alive) console.warn(`[dsh-crossterm] 总开关(入口组件)未启用,组件「${PART_LABEL[part]}」已跳过挂载`)
1876
+ }, 3000)
1877
+ if (timer && typeof timer.unref === 'function') timer.unref()
1878
+ }
1879
+ root.inject(isMaster ? ['agents'] : ['agents', 'crossterm'], (ctx) => {
1863
1880
  // 四个组件跑在同一个进程里,共用一份总线实例:各自只挂自己那组工具,
1864
1881
  // 心跳/云同步只在第一个组件加载时启动一次,最后一个组件卸载时才停。
1865
1882
  const term = acquireTerm(ctx)
package/lib/web.js CHANGED
@@ -316,6 +316,8 @@ function aboutOf() {
316
316
  name: PKG,
317
317
  version: VERSION,
318
318
  title: meta.title || PKG,
319
+ // 插件页顶部标题要带「(总开关)」才看得懂这一行是什么,但卡片头用短名更清爽
320
+ shortTitle: meta.shortTitle || meta.title || PKG,
319
321
  description: meta.description || '',
320
322
  components,
321
323
  changelog: readChangelog(),
package/locale/en.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "meta": {
3
- "title": "CrossTerm",
4
- "description": "Connect sessions, terminals and devices of one DSH account: chain codes, inline mail, a cloud relay and automatic backups. Four components, each with its own switch."
3
+ "title": "CrossTerm (master switch)",
4
+ "shortTitle": "CrossTerm",
5
+ "description": "Master switch: turning this off stops everything below — tools, heartbeat, cloud sync, cloud relay and session backups for all four components (cross-session / cross-terminal / cross-device / cross-account). While it is on, each component can still be switched off individually."
5
6
  }
6
7
  }
package/locale/zh.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "meta": {
3
- "title": "跨端互通",
4
- "description": "同一 DSH 账号下的会话、终端、设备之间互通:特征码链、内联邮件、云端中转站与自动备份。四个组件可单独开关。"
3
+ "title": "跨端互通(总开关)",
4
+ "shortTitle": "跨端互通",
5
+ "description": "总开关:关掉这一项,下面四个组件(跨会话 / 跨终端 / 跨设备 / 跨账号)全部停用 —— 工具、心跳、云同步、云端中转站与会话备份一起停。开着它时,四个组件可各自单独开关。插件简介:同一 DSH 账号下的会话、终端、设备之间互通。"
5
6
  }
6
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-crossterm",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "跨端互通:同一 DSH 账号下的会话、终端、设备之间互通 —— 特征码链、内联邮件、云端中转站与自动备份",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",