dsh-workspace-mover 2.2.0 → 2.4.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.
@@ -0,0 +1,37 @@
1
+ # 2026-10-18 compatibility fixes (unreleased)
2
+
3
+ - Plugin baseline: 2.3.0; package version unchanged. No GitHub push or npm publication.
4
+ - Source review: official DSH `dsh-v0.2.1-rc.2`; compared JSONL writer lifecycle with `dsh-v0.2.0-rc.2`.
5
+ - Environment: Windows, Node v22.23.2 local sandbox. Desktop/Web runtime acceptance is pending.
6
+ - Fixtures: constructed JSONL records using the official v4 header `version` and event envelope (`type`, `seq`, `time`, `data`). These are sandbox fixtures, not a captured official runtime session.
7
+
8
+ ## Changed behavior
9
+
10
+ 1. Resident sessions, including idle sessions, wait for unloading before physical migration. Current DSH exposes no public writer rebind API. The plugin no longer replaces live headers or clears private coordinator state. Workspace repoint refuses resident sessions before changing the registry path.
11
+ 2. Cold migration awaits backend `flush()` when available, then checks residency and running state again. A flush failure aborts before backup/detach.
12
+ 3. Migration sets the effective working directory to the target workspace. Original working-directory events remain intact; a final `working-directory/change` is appended when needed. Its sequence must follow a contiguous v3/v4 log. Unrecognized formats or invalid sequences abort before detach. The working-directory checkpoint is invalidated so replay sees the new directory.
13
+ 4. Backup restore uses the official header version for v3/v4 filenames. Headers without generation metadata restore as unversioned legacy JSONL. Plain and Zstd are both covered.
14
+ 5. Bundle manifests take `pluginVersion` from package.json.
15
+
16
+ Working-directory events are actual log changes, so sessions with such changes can need new recovery snapshots on subsequent moves. Existing snapshot retention limits still apply. Sessions whose content only changes in header cwd continue to reuse a snapshot.
17
+
18
+ ## Local verification
19
+
20
+ The regression suite covers resident queueing and retry after unloading, a session loaded during flush, flush failure, snapshots including flushed data, repoint refusal without registry mutation, working-directory replay and byte-exact attach-failure rollback, plain/Zstd backup restore for legacy/v3/v4, and the exported plugin version. Full suite: 180 tests passed, 0 failed (Node v22.23.2). Syntax checks passed for lib/index.js and client/client.js. npm pack --dry-run --json passed (29 packaged files); no archive was published. git diff --check passed.
21
+
22
+ ## Desktop acceptance checklist
23
+
24
+ Use disposable sessions and two test workspaces A and B. Test after loading this local source; the published npm version does not contain these changes.
25
+
26
+ 1. Open a session in A, finish its current turn, then request migration to B. Expect a waiting task, no directory move, and a message about its resident writer. Merely becoming idle must not bypass the guard.
27
+ 2. Close/unload that session, or restart DSH without reopening it. The durable migration task should finish. Reopen it in B and send a message. Confirm new events appear under B, with no new archive in A. Restart once more and confirm the session still loads.
28
+ 3. On DSH 0.2.1-rc.2, change a disposable session's working directory before migration. Unload it, migrate A to B, then reopen it. The effective working directory should be B; original directory-change history should remain, followed by a change to B. Test the return move as well.
29
+ 4. Create a recovery snapshot for a disposable v4 session, remove that test session through the rescue UI, then restore its backup. Expect `session.v4.jsonl[.zstd]`, successful reopening, and no generation mismatch in doctor.
30
+ 5. Try workspace repoint while an affected session is resident. Expect refusal and the original registry path to remain. Unload the session and retry.
31
+
32
+ ## Remaining validation
33
+
34
+ - Actual DSH Desktop and Web runtime: not run in this audit.
35
+ - Official runtime v4 session replay and continued writing: pending user acceptance.
36
+ - Node 22/24 matrix: local runtime only; CI has not run for these uncommitted changes.
37
+ - Host session loading concurrent with migration is not coordinated by a public host lifecycle lock. Plugin locks serialize plugin operations; residency is checked again before file replacement. Keep the test session closed while its queued move completes.
@@ -0,0 +1,106 @@
1
+ # Issue #5:2.4.0-rc.1 Desktop 验收
2
+
3
+ 状态:用户已完成候选版本 `2.4.0-rc.1` 的 Desktop 验收并授权提交、合并和发布。自动滚动的人工验收由用户明确豁免,保留自动 DOM 检查结果。
4
+
5
+ ## 已确认的环境
6
+
7
+ - Desktop 安装目录:`E:\DeepSeekHarness\desktop`。
8
+ - 安装包中的持久化、会话和工具服务版本:`0.2.1-rc.2`;Cordis:`4.0.5`。
9
+ - Desktop profile 中 `dsh-workspace-mover` 链接到 `E:\DeepSeekHarness\dsh-workspace-mover`。
10
+ - 本地候选版本:`2.4.0-rc.1`。计划正式发布版本:`2.4.0`。
11
+
12
+ ## 1. 加载候选版本
13
+
14
+ 1. 等待正在运行的回合结束,正常退出 DeepSeek Harness。若关窗口后仍在托盘运行,使用托盘菜单的退出项。
15
+ 2. 重新打开 `E:\DeepSeekHarness\desktop\DeepSeek Harness.exe`。
16
+ 3. 打开设置中的会话修复面板,点击“自检”。结果摘要末尾应显示 `v2.4.0-rc.1`。
17
+ 4. 也可以在测试对话中要求“调用 mover_doctor,原样报告 pluginVersion 和失败项”。应返回 `2.4.0-rc.1`。如果版本不符,先停止验收并反馈。
18
+
19
+ `filesystem-fallback` 提示本身不是失败:宿主尚无公开的原始档案迁移接口。自检如有 `fail` 项,请提供具体项目与内容。
20
+
21
+ ## 2. 准备工作区
22
+
23
+ 以下三个空目录已由本次工作创建。让 Agent 执行:
24
+
25
+ > 仅使用 mover_create_workspace,登记以下已有目录,不创建或搬动文件:
26
+ > 名称 WSM-A-1022,目录 E:\DeepSeekHarness\data\pr-review-20261022\acceptance\A;
27
+ > 名称 WSM-B-1022,目录 E:\DeepSeekHarness\data\pr-review-20261022\acceptance\B;
28
+ > 名称 WSM-C-1022,目录 E:\DeepSeekHarness\data\pr-review-20261022\acceptance\C。
29
+
30
+ 预期:出现三个工作区;登记不弹插件审批框;重复登记应报告冲突,不能修改已有名称。
31
+
32
+ ## 3. 已打开会话排队、重启迁移、继续发送
33
+
34
+ 1. 在 A 新建测试会话,发送“迁移验收 A1,请只回复 A1 收到”,等待回复结束。
35
+ 2. 将该会话拖到 B,确认迁移。预期:提示排队、等待释放写入句柄,可能需要重启;不能提示已经迁移完成。
36
+ 3. 在原会话继续发送“A2,请只回复 A2 收到”。预期:正常回复,无旧路径写入报错。
37
+ 4. 在 C 新建另一个测试会话,发送“重启停留页”。保持选中 C 的会话,再正常彻底退出 DSH。这样重启时不会自动打开待迁移的 A 会话、再次占用它的写入句柄。
38
+ 5. 重启后先停留在 C,等待约 10 秒。在修复面板的迁移队列查看任务是否完成。等待期间不要打开待迁移会话。
39
+ 6. 任务完成后,在 B 打开迁移会话,发送“B1,请只回复 B1 收到”。预期:正常回复,A1/A2 历史完整,没有重复会话。
40
+ 7. 让 Agent 报告当前会话的有效工作目录。预期为 `E:\DeepSeekHarness\data\pr-review-20261022\acceptance\B`。
41
+ 8. 再切换到 C,彻底退出并重启一次。确认会话仍在 B,再发送“B2,请只回复 B2 收到”。不应重复迁移、重复追加记录或出现旧目录错误。
42
+
43
+ 如果任务一直等待,保留任务,提供自检结果和队列原因;不要手动移动 sessions 文件。
44
+
45
+ ## 4. 工作区改名与审批
46
+
47
+ 在普通权限模式下,让 Agent 使用 `mover_rename_workspace` 把 C 改名为 `WSM-C-1022-renamed`:
48
+
49
+ 1. 第一次在审批框拒绝:名称必须保持不变。
50
+ 2. 再次请求并批准:名称应更新,路径仍为 C,原会话可打开。
51
+ 3. 改成 A 的已有名称:应直接拒绝,不弹一个注定失败的审批框。
52
+ 4. 改成当前名称:应返回无需修改,不弹框。
53
+
54
+ 在 DSH 的完全访问模式下,再把 C 改回 `WSM-C-1022`:应成功,插件不请求额外审批。切换权限模式属于宿主操作,如宿主另有确认按其提示处理。
55
+
56
+ 审批服务缺失时,普通模式改名、迁移和修复工具必须拒绝执行,提示使用面板;不要求你卸载服务,这条由自动检查覆盖。登记已有目录无需审批;完全访问免审批仅适用于改名,未放宽原有迁移/修复审批。
57
+
58
+ ## 5. 自动滚动
59
+
60
+ 已有工作区足够多、侧栏出现滚动条时直接验证。如果不足,可让 Agent 使用 `mover_create_workspace`,登记验收目录下 `scroll-01` 到 `scroll-12` 的已有目录,名称设为 `WSM-scroll-01` 到 `WSM-scroll-12`。
61
+
62
+ 1. 拖动专用测试会话,指针停在侧栏底部边缘。预期:持续向下滚动,能够看到原先在视口外的工作区。
63
+ 2. 移到侧栏顶部:应向上滚动;移到中间、侧栏之外、松手或取消拖动:应停止。
64
+ 3. 到达最顶部/最底部后应稳定停止,不抖动。
65
+ 4. 实际投放一次:确认框目标应与投放工作区一致;已打开会话仍按第 3 节排队。
66
+
67
+ 插件卸载时取消滚动动画由自动 DOM 检查覆盖,无需你反复卸载插件。
68
+
69
+ ## 反馈格式
70
+
71
+ ```text
72
+ 版本:2.4.0-rc.1 / 其他
73
+ 排队后 A2 回复:通过 / 失败(错误)
74
+ 切换 C 并重启后任务:完成 / 等待(原因)/ 失败
75
+ B1、B2 回复及历史:通过 / 失败
76
+ 有效工作目录:
77
+ 普通模式拒绝/批准改名:通过 / 失败
78
+ 完全访问改名:通过 / 失败
79
+ 自动滚动与停止:通过 / 失败
80
+ 自检 fail 项:无 / 内容
81
+ ```
82
+
83
+ 验收通过后才进行提交、推送、PR 合并及正式发布。失败时先修复并重新验证相关步骤。
84
+
85
+ ## 2026-10-22 用户实际验收记录
86
+
87
+ 以下为用户在本会话中报告的实测结果,未将自动检查冒充人工验收:
88
+
89
+ | 项目 | 结果 |
90
+ | --- | --- |
91
+ | 自检版本 | 摘要显示 `v2.4.0-rc.1`,自检正常 |
92
+ | 登记 A/B/C | 三个工作区出现,无插件审批框 |
93
+ | 打开会话拖到 B | 预览明确提示“会进入迁移等待队列(可能需重启)”,提示驻留会话/写入句柄尚未关闭 |
94
+ | 等待期间 A2 | 正常回复,无错误 |
95
+ | 切换 C 后彻底退出并重启 | 最近移动中记录迁移任务;会话从 A 消失并出现在 B |
96
+ | 迁移后 B1 与工作目录 | 正常回复,有效工作目录为 B |
97
+ | 再次重启后 B2 | 回复 B2 收到,无报错,自检正常 |
98
+ | 普通模式拒绝改名 | 名称仍为 WSM-C-1022 |
99
+ | 重试并批准改名 | 显示名更新,路径和 workspaceId 不变,会话仍可访问 |
100
+ | 重名/相同名称 | 重名直接 conflict;同名 changed:false,均无审批框 |
101
+ | 完全访问模式改回原名 | 成功 |
102
+ | 自动滚动 | 用户因工作区较少明确跳过人工验收,并授权直接提交;自动 DOM 检查通过 |
103
+
104
+ 用户未逐字重述全部历史消息的完整性比对;已确认迁移后和两次重启后继续发送成功。此前真实后端检查验证完整记录数量和追加写入。
105
+
106
+ 验收中提及 C 下的 `_acl-recovery` 属于另一会话的权限修复记录,本次不删除、不纳入插件发布。Desktop 启动权限修复独立于此版本;未把安装目录权限操作加入插件。
@@ -0,0 +1,56 @@
1
+ # Issue #5 / PR 整合审查与验证
2
+
3
+ 日期:2026-10-22。候选版本 `2.4.0-rc.1`,正式目标 `2.4.0`。
4
+ 状态:用户 Desktop 验收通过并授权交付;自动滚动人工验收明确豁免。生产代码 SHA256 与已验收候选一致,正式版只更新版本元数据和交付文档。
5
+
6
+ ## 固定审查版本
7
+
8
+ | PR | 作者 | Head SHA | 本次处理 |
9
+ | --- | --- | --- | --- |
10
+ | [#6](https://github.com/PianoPrince/dsh-workspace-mover/pull/6) | Arrosam | `a2d333dca7fafdb2d0f973d0ac56f83809c89263` | 不合并;保留安全排队策略 |
11
+ | [#7](https://github.com/PianoPrince/dsh-workspace-mover/pull/7) | Arrosam | `689088a331c762af9f9bca721834e3238af4faec` | 本地整合,收紧缺失审批的处理 |
12
+ | [#8](https://github.com/PianoPrince/dsh-workspace-mover/pull/8) | Arrosam | `978b7f55c6a346b0641e6e7b1fd634ab91bc14aa` | 本地整合,仅吞 ENOENT |
13
+ | [#9](https://github.com/PianoPrince/dsh-workspace-mover/pull/9) | lsb0554 | `1dad18ebf8d43eb73edf0ca1b600b228da00c0c1` | 本地整合,补滚动停止与卸载释放 |
14
+
15
+ 实施结束时通过 `git ls-remote` 再次确认,四个 Head 均未变化。原始提交已保留在本地 `refs/remotes/review/pr-N`,未改写贡献者分支。
16
+
17
+ ## 代码安全审查
18
+
19
+ 审查覆盖四个 PR 相对其 merge-base 的完整改动,包括生产代码、测试、文档和 package 脚本。未发现明显恶意代码或新增的外传请求、凭据读取、动态代码执行、子进程调用、混淆载荷。四个 PR 均未修改 CI/发布工作流,未新增依赖或安装生命周期脚本;#7 的 package 改动只增加测试入口。新增测试中的文件读写、环境变量和递归清理均围绕独立临时夹具目录。
20
+
21
+ 发现并修正的实际风险:
22
+
23
+ - #6 重绑定失败时仍继续搬文件,且缺少宿主写入链的互斥;本次不采用其内部句柄重绑定实现。
24
+ - #7 移除必需审批服务注入后,旧的“服务缺失直接执行”分支变得可达。本次改为需要审批时拒绝执行;不允许缺失调用方会话却从全局策略推断完全访问。完全访问改名免审批、登记已有目录免审批保留。迁移和修复未新增完全访问豁免。
25
+ - #8 原实现使用吞掉所有 stat 错误的辅助函数,会将权限/I/O 故障显示为空库;改为直接读取,只把 ENOENT 视为空。
26
+ - #9 补齐横纵范围、滚动边界、dragend/drop/dragleave 和热卸载取消动画,避免侧栏外继续滚动或旧闭包持续排帧。
27
+
28
+ 上述为指定版本的静态审查与运行检查结论。PR 后续更新时需复核新增差异。
29
+
30
+ ## Issue #5 实现
31
+
32
+ - 驻留会话、JSONL tracker 中打开中(值为 null)或关闭中的 writer、旧 coordinator 中的句柄都阻止物理搬移。
33
+ - 未知 handle 后端或无法读取的写入状态暂停并进入队列;不把未知状态当成安全。
34
+ - 冷迁移前 flush 并重新检查。detach 后再检查,忙碌时恢复归属并保持可重试的 busy 错误码。
35
+ - 最后一次写入状态检查到 header 改写、目录移动和目标字节验证之间不让出 JavaScript 执行权,避免 await 引入的同进程写入竞态。
36
+ - 保留此前未提交的工作目录事件、投影失效、备份代际、标题和 Bundle 版本修复。
37
+ - 私有 tracker/coordinator 仅用于读取占用状态,不修改 writer/header。宿主改变内部结构时可能暂停迁移,需通过自检确认兼容性;没有承诺未知后端立即迁移。
38
+
39
+ ## 已完成验证
40
+
41
+ - Windows / Node `22.23.2`:`npm run check` 通过,315 项测试全部通过,语法和 npm 打包预检通过。
42
+ - `git diff --check` 通过。
43
+ - 使用已安装 Desktop 的 DSH `0.2.1-rc.2` 和 Cordis `4.0.5`,在独立临时目录运行 `test/installed-host.test.mjs`,1 项通过。实际加载官方 Cordis、ToolRuntime、JSONL 和 Windows 原生锁实现,未替换持久化 writer。
44
+ - 真实后端检查:缺少 tools/approval 时 RPC 仍挂载;tools 服务装卸更新能力位;打开 writer 时请求迁移不改源文件;继续追加、缓冲 live 事件;关闭时排空;重新加载插件和后端后持久化队列自动完成;新路径重新打开可追加;重复重试不重复写;再加载后历史仍可读。
45
+ - 自动检查还覆盖回滚、v3/v4 与 plain/Zstd、缺失根目录、EACCES/EIO/ENOTDIR、创建/改名冲突和审批拒绝、自动滚动停止与热卸载。
46
+
47
+ 可选真实后端检查通过 `DSH_TEST_NODE_MODULES` 指向已有宿主依赖,再运行 `npm run test:installed-host`。未设置变量时明确 skip,不用模拟结果冒充真实后端通过。依赖提取脚本与结果保留在 `E:\DeepSeekHarness\data\pr-review-20261022`;不读用户凭据、不改 Desktop 安装。
48
+
49
+ ## 交付阶段
50
+
51
+ 1. 用户已完成真实 UI 拖动、发送消息、两次进程重启、工作目录与改名验收,详见 [Desktop 验收记录](issue-5-desktop-acceptance-2026-10-22.md)。自动滚动人工验收由用户明确跳过。
52
+ 2. 用户确认后,再提交修复,依次处理 #8、#9、#7 的合并冲突和修正;保留贡献者来源,#6 保持开放。
53
+ 3. 合并后最终提交通过仓库现有跨平台 CI(Linux/macOS/Windows × Node 22/24)。当前只有本地 Windows 结果。
54
+ 4. 正式版本改为 `2.4.0`,更新发布说明并重新验证版本相关输出,随后发布 GitHub/npm。最终记录提交、合并与发布链接。
55
+
56
+ 用户已明确授权在上述验收结果基础上提交、合并和发布。既有未跟踪 `issue_page.html` 属于历史工作,本次保留,不纳入发布文件。