dsh-crossterm 0.6.0 → 0.6.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/CHANGELOG.md +17 -0
- package/README.md +12 -9
- package/lib/bus.js +1 -1
- package/lib/cloud/layout.js +27 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# dsh-crossterm 变更记录
|
|
2
2
|
|
|
3
|
+
## 0.6.1 — 2026-10-19
|
|
4
|
+
|
|
5
|
+
### 修:旧布局缓存挡住了新增的云端文档
|
|
6
|
+
- 症状:0.5.0 / 0.6.0 升级后,云盘里看不到 `_规则-账号.md`、`_规则-设备.md`、`inbox/_说明.md`,
|
|
7
|
+
`status.home.layout.rulesVersion` 也还是老值 —— 文档写着「命中缓存会自动补写」,实际没补。
|
|
8
|
+
- 根因:`ensureLayout()` 命中缓存时直接沿用 `cached.paths`,而路径是**算出来的**(`buildPaths()`)。
|
|
9
|
+
旧版缓存里没有 `accountRulesFile` / `deviceRulesFile` / `inboxReadmeFile` 三个字段,
|
|
10
|
+
`ensureRules()` 拿到 `undefined` 就跳过,随后仍把 `rulesVersion` 标成最新 —— 等于自己认定「已写」。
|
|
11
|
+
- 修法(`lib/cloud/layout.js`):
|
|
12
|
+
- 命中缓存时用 `buildPaths()` 按 `home / account / deviceId` **重新算路径**,缓存只负责存 `account`、`role`、`ensuredAt` 这类状态;
|
|
13
|
+
- `ensureRules()` 返回 `{ written, failed }`,路径缺失或上传失败都计入 `failed`;
|
|
14
|
+
- 只有 `failed === 0` 才把 `rulesVersion` 抬到 `RULES_VERSION` 并写回缓存,否则保持 0,下次 `ensure` 继续重试;
|
|
15
|
+
- 缓存新增 `home` 字段,非默认 `cloudHome` 也能重建路径。
|
|
16
|
+
- 探针 `F:\dsh\001X\crossterm-work\probe-layout-stale-cache.mjs`:**12 项全 PASS**
|
|
17
|
+
(旧缓存→重算路径→补写三份文档→写回新缓存;第二次不重复上传;上传失败时 `rulesVersion` 不冒充最新)。
|
|
18
|
+
回归:`probe-layout-rules.mjs` 26 PASS、`probe-cloud-home.mjs` 42 PASS、`probe-inbox-readme.mjs` 17 PASS。
|
|
19
|
+
|
|
3
20
|
## 0.6.0 — 2026-10-19
|
|
4
21
|
|
|
5
22
|
### 共享收件箱里也放一份说明
|
package/README.md
CHANGED
|
@@ -23,15 +23,18 @@ A 终端看不到 B 终端里有哪个会话、在干什么,也没法把一条
|
|
|
23
23
|
| 跨设备 | 经云端总线,在多台机器的 DSH 之间互发邮件与文件 | `term_cloud` |
|
|
24
24
|
| 跨账号 | 预留位:后续用于跨账号互通,当前不挂工具 | — |
|
|
25
25
|
|
|
26
|
-
**本版更新(0.6.
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- `
|
|
34
|
-
|
|
26
|
+
**本版更新(0.6.1)**
|
|
27
|
+
|
|
28
|
+
- **修:旧布局缓存把新增的云端文档挡住了**。0.5.0 / 0.6.0 说「命中旧缓存会自动补写」,实际没补 ——
|
|
29
|
+
云盘里根本没有 `_规则-账号.md`、`_规则-设备.md`、`inbox/_说明.md`。
|
|
30
|
+
- 根因:`ensureLayout()` 命中缓存时直接沿用 `cached.paths`,而路径是 `buildPaths()` **算出来的**;
|
|
31
|
+
旧缓存没有 `accountRulesFile` / `deviceRulesFile` / `inboxReadmeFile` 三个字段,`ensureRules()` 拿到 `undefined`
|
|
32
|
+
就跳过,还照样把 `rulesVersion` 标成最新。
|
|
33
|
+
- 修法:命中缓存时按 `home / account / deviceId` 重新算路径;`ensureRules()` 返回 `{ written, failed }`,
|
|
34
|
+
**只有 `failed === 0` 才把 `rulesVersion` 抬上去**,否则保持 0 下次继续重试。
|
|
35
|
+
- 探针 `probe-layout-stale-cache.mjs` 12 项全 PASS(旧缓存→重算→补写三份文档→写回新缓存;
|
|
36
|
+
第二次不重复上传;上传失败时不冒充最新),回归 26 + 42 + 17 项全 PASS。
|
|
37
|
+
- 上一版(0.6.0)的内容仍在:共享收件箱里的 `_说明.md`、中转站 `isEnvelopeFile()` 只认 `.json` 信封。
|
|
35
38
|
|
|
36
39
|
## 一、安装与卸载
|
|
37
40
|
|
package/lib/bus.js
CHANGED
package/lib/cloud/layout.js
CHANGED
|
@@ -242,17 +242,22 @@ export async function ensureRules(pan, paths, info = {}) {
|
|
|
242
242
|
]
|
|
243
243
|
if (paths.inboxReadmeFile) docs.push([paths.inboxReadmeFile, inboxReadmeMarkdown({ account, device, version })])
|
|
244
244
|
const written = []
|
|
245
|
+
let failed = 0
|
|
245
246
|
for (const [remote, text] of docs) {
|
|
246
247
|
try {
|
|
248
|
+
if (!remote) { failed += 1; continue }
|
|
247
249
|
if (await pan.exists(remote)) continue
|
|
248
250
|
await pan.putBuffer(Buffer.from(text, 'utf8'), remote)
|
|
249
251
|
written.push(remote)
|
|
250
252
|
log(`云端规则已写入:${remote}`)
|
|
251
253
|
} catch (e) {
|
|
254
|
+
failed += 1
|
|
252
255
|
log(`写云端规则失败 ${remote}:${(e && e.message) || String(e)}`)
|
|
253
256
|
}
|
|
254
257
|
}
|
|
255
|
-
|
|
258
|
+
// 收件箱说明算一份必须存在的文档:缺少它的旧路径缓存不能冒充「规则已是最新」
|
|
259
|
+
if (!paths.inboxReadmeFile) failed += 1
|
|
260
|
+
return { written, failed }
|
|
256
261
|
}
|
|
257
262
|
|
|
258
263
|
/**
|
|
@@ -263,18 +268,29 @@ export async function ensureLayout({ pan, cfg = {}, device = {}, cacheFile, forc
|
|
|
263
268
|
const nodeId = sanitize(device.nodeId || 'device')
|
|
264
269
|
const cached = readCache(cacheFile)
|
|
265
270
|
if (!force && cached && cached.deviceId === nodeId && Date.now() - Number(cached.at || 0) < CACHE_MS && cached.paths) {
|
|
271
|
+
// 路径是「算出来的」而不是状态:升级后新增的路径(规则文档、收件箱说明)必须重新算,
|
|
272
|
+
// 直接沿用旧缓存的 paths 会让 ensureRules 拿到 undefined、规则永远写不出去。
|
|
273
|
+
const paths = buildPaths({
|
|
274
|
+
home: cached.home || cfg.cloudHome || DEFAULT_HOME,
|
|
275
|
+
account: cached.account || cached.paths.account || 'default',
|
|
276
|
+
deviceId: nodeId,
|
|
277
|
+
})
|
|
278
|
+
const state = { ...cached, home: cached.home || cfg.cloudHome || DEFAULT_HOME, paths }
|
|
266
279
|
if (Number(cached.rulesVersion || 0) < RULES_VERSION) {
|
|
267
|
-
await ensureRules(pan,
|
|
280
|
+
const r = await ensureRules(pan, paths, {
|
|
268
281
|
log,
|
|
269
|
-
account:
|
|
282
|
+
account: state.account,
|
|
270
283
|
device: nodeId,
|
|
271
|
-
role:
|
|
284
|
+
role: state.role,
|
|
272
285
|
version: device.version || '',
|
|
273
286
|
})
|
|
274
|
-
|
|
275
|
-
|
|
287
|
+
if (!r.failed) {
|
|
288
|
+
state.rulesVersion = RULES_VERSION
|
|
289
|
+
state.rulesWritten = r.written
|
|
290
|
+
writeCache(cacheFile, state)
|
|
291
|
+
}
|
|
276
292
|
}
|
|
277
|
-
return { ...
|
|
293
|
+
return { ...state, cached: true, ensuredAt: cached.at }
|
|
278
294
|
}
|
|
279
295
|
|
|
280
296
|
const who = await resolveAccount(pan, cfg, log)
|
|
@@ -358,9 +374,12 @@ export async function ensureLayout({ pan, cfg = {}, device = {}, cacheFile, forc
|
|
|
358
374
|
deviceId: nodeId,
|
|
359
375
|
account: who.account,
|
|
360
376
|
accountSource: who.source,
|
|
377
|
+
home: cfg.cloudHome || DEFAULT_HOME,
|
|
361
378
|
role,
|
|
362
|
-
|
|
379
|
+
// 有文档没写成功就不要把版本号标上去,下次 ensure 还会重试
|
|
380
|
+
rulesVersion: rules.failed ? 0 : RULES_VERSION,
|
|
363
381
|
rulesWritten: rules.written,
|
|
382
|
+
rulesFailed: rules.failed,
|
|
364
383
|
paths,
|
|
365
384
|
created,
|
|
366
385
|
accountInfo,
|