dsh-crossterm 0.8.3 → 0.8.4

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,18 @@
1
1
  # dsh-crossterm 变更记录
2
2
 
3
+ ## 0.8.4 — 2026-10-19
4
+
5
+ ### 修备份统计口径:卡片上「已归档 0/24 · 活跃中 38/10」
6
+
7
+ - **症状**:0.8.3 的卡片显示 `已归档 0/24 · 活跃中 38/10` —— 归档明明全备过,活跃数还超过了总数。
8
+ - **根因**:统计用了状态里的 `archived` 标记,而升级前的历史条目(0.8.2 及更早写进 `backup-state.json` 的)
9
+ 没有这个字段 → `archivedDone` 恒为 0;`activeDone` 又是用「总条目 − archivedDone」算的,于是把归档的也算进活跃。
10
+ - **改法**:`backed(x)` 改为「状态里这一条存在且 `bytes > 0`」才算已备,不再依赖标记;
11
+ 跳过已归档会话时顺手把 `archived: true` 补进状态(以后口径不会漂);`archivedUntouched` 改由
12
+ 「归档总数 − 已备归档数」得出。
13
+ - 探针 `probe-archived-backup.mjs` **16 PASS**(含首轮 `archivedBackedUp=2 / activeBackedUp=2`、次轮全跳过)。
14
+ - **要不要跟着动手:不用**(只是计数与文案,装上即可)。
15
+
3
16
  ## 0.8.3 — 2026-10-19
4
17
 
5
18
  ### 已归档会话只备份一次,卡片把备份拆成「已归档 / 活跃中」
package/README.md CHANGED
@@ -28,7 +28,13 @@ A 终端看不到 B 终端里有哪个会话、在干什么,也没法把一条
28
28
  > `locatePkgJson()` 对子路径行返回 undefined),而插件页顶部标题与这一行共用同一份 `locale/zh.json` 的 meta,
29
29
  > 所以它单独做总开关,标题带「(总开关)」;卡片头用 `shortTitle` 显示短名「跨端互通」。
30
30
 
31
- **本版更新(0.8.3)**
31
+ **本版更新(0.8.4)**
32
+
33
+ - **修上一版的一个统计口径**:0.8.3 卡片一度显示 `已归档 0/24 · 活跃中 38/10`(历史备份记录里没有归档标记,
34
+ 被当成没备过、还算进了活跃)。现在按「状态里有字节」算已备,显示恢复成 `已归档 24/24 · 活跃中 10/10`。
35
+ - 备份行为本身没变:归档会话仍然只传一次,活跃会话仍按水位增量。
36
+
37
+ **上一版(0.8.3)**
32
38
 
33
39
  - **已归档会话不再反复备份**:备份前先读 DSH 的归档清单(`storages/workspace.json`),
34
40
  归档会话第一次传完就标记,之后每轮直接跳过(本机 24 个已归档、9 个活跃中)。
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.8.3'
25
+ export const VERSION = '0.8.4'
26
26
 
27
27
  /** DSH 的家目录:与宿主其它状态(sessions / profiles)同一个根,多终端天然共享 */
28
28
  export function dshHome() {
@@ -117,6 +117,8 @@ export async function backupSessions({ pan, layout, sessionsRoot, tmpDir, stateF
117
117
  result.archived.skipped += 1
118
118
  continue
119
119
  }
120
+ // 旧版本的状态里没有 archived 字段;这里顺手补上,避免统计口径漂移
121
+ if (item.archived && !prev.archived && state.sessions[item.sessionId]) prev.archived = true
120
122
  if (prev.bytes === item.size) {
121
123
  result.skipped += 1
122
124
  if (item.archived) result.archived.skipped += 1
@@ -172,13 +174,18 @@ export async function backupSessions({ pan, layout, sessionsRoot, tmpDir, stateF
172
174
  break
173
175
  }
174
176
  }
175
- const archivedDone = archivedAll.filter((x) => state.sessions[x.sessionId] && state.sessions[x.sessionId].archived).length
177
+ const backed = (x) => {
178
+ const row = state.sessions[x.sessionId]
179
+ return Boolean(row && Number(row.bytes || 0) > 0)
180
+ }
181
+ const archivedDone = archivedAll.filter(backed).length
182
+ const activeDone = activeAll.filter(backed).length
176
183
  state.lastRun = {
177
184
  at: Date.now(),
178
185
  archivedTotal: archivedAll.length,
179
186
  activeTotal: activeAll.length,
180
187
  archivedDone,
181
- activeDone: Math.max(0, Object.keys(state.sessions).length - archivedDone),
188
+ activeDone,
182
189
  }
183
190
  saveState(stateFile, { ...state, at: Date.now() })
184
191
  return result
@@ -246,7 +253,7 @@ export function backupSummary(stateFile) {
246
253
  active: Number(run.activeTotal || 0),
247
254
  archivedBackedUp,
248
255
  activeBackedUp,
249
- archivedUntouched: sessions.filter((s) => s.archived).length,
256
+ archivedUntouched: Math.max(0, Number(run.archivedTotal || 0) - archivedBackedUp),
250
257
  bytes: sessions.reduce((a, s) => a + Number(s.bytes || 0), 0),
251
258
  attachments: Object.keys(state.attachments).length,
252
259
  attachmentBytes: Object.values(state.attachments).reduce((a, s) => a + Number(s.size || 0), 0),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-crossterm",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "跨端互通:同一 DSH 账号下的会话、终端、设备之间互通 —— 特征码链、内联邮件、云端中转站与自动备份",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",