dsh-recall-plugin 2.0.0 → 2.1.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 +63 -29
- package/README.en.md +2 -1
- package/README.md +2 -1
- package/lib/client.js +1459 -1479
- package/lib/diagnostics.js +59 -0
- package/lib/errors.js +73 -0
- package/lib/index.js +426 -1129
- package/lib/routes-core.js +162 -0
- package/lib/routes-manage.js +541 -0
- package/lib/scripts.posix.js +195 -27
- package/lib/scripts.pwsh.js +194 -33
- package/lib/session-info.js +71 -0
- package/lib/snapshots.js +243 -39
- package/lib/store.js +157 -19
- package/package.json +65 -61
package/CHANGELOG.md
CHANGED
|
@@ -2,41 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
本文件格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循语义化版本。
|
|
4
4
|
|
|
5
|
-
## [2.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
###
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
5
|
+
## [2.1.1] - 2026-08-29
|
|
6
|
+
|
|
7
|
+
issue #12 换行符字节保真修复(patch)。单测 227 项全绿,双平台真实模板端到端复验(pwsh 全新/存量迁移 + POSIX 实弹)31 项全过,`check:dsh` 巡检一致。
|
|
8
|
+
|
|
9
|
+
### 修复
|
|
10
|
+
|
|
11
|
+
- **快照/回退换行符失真(issue #12)**:影子仓库固化为字节保真语义——`info/attributes`(`FIDELITY_ATTRS`)对全部路径关闭 EOL 转换、clean filter、`$Id$` 展开、`export-ignore`/`export-subst`、`working-tree-encoding`。根因是 `git archive`(回退恢复路径)与 `git add`(捕获路径)都会应用快照树里项目自己的 `.gitattributes`:`text=auto` + Windows 缺省 `core.eol=native` 会把 LF 转 CRLF,仓库级 `core.autocrlf=false` 挡不住(属性驱动的转换看 `core.eol`)。存量归一化索引经一次性 `git add --renormalize -- ':(top)'` 迁移(标记文件 `attrs-v1.stamp` 防重复,迁移失败不阻塞快照)。连带修复 `export-ignore` 声明让文件从回退归档中静默消失的同类缺口。注意:回退到本版之前的旧快照仍会还原归一化内容(旧 blob 信息已物理丢失),本版起的新快照字节保真。
|
|
12
|
+
|
|
13
|
+
## [2.1.0] - 2026-08-29
|
|
14
|
+
|
|
15
|
+
改进专项与审查修复、环境诊断批次(错误治理 / POSIX home 三档 / 并发治理)、双平台实弹冒烟(Windows + WSL2 Ubuntu 26.04)后发版。单测 224 项、官方 API 探针、`verify:host`、`check:dsh` 全绿。
|
|
16
|
+
|
|
17
|
+
### 新增
|
|
18
|
+
|
|
19
|
+
- **回退失败救援闭环**(H1):rollback 未输出 ROLLBACK_OK(工作区可能半回退)时,用 execute 预先打下的安全快照(`snap-pre-rollback-<ts>`)自动 reset 回「回退前」状态,提示含「已自动恢复」;救援也失败时给出可直接复制执行的手动命令(空格路径已实弹验证)。
|
|
20
|
+
- **索引原子写与损坏隔离**(H2):index.json/lineage.json 走 tmp+rename 原子写;内容损坏或形状非法时 fail-loud——坏文件改名 `.corrupt-<ts>` 保留现场并告警,孤儿从 tag 重建(时间从 tag creatordate 恢复),不再静默当空。
|
|
21
|
+
- **错误码单一事实源**(H3):`lib/errors.js` 收敛 18 个错误码;无快照撤回 / STALE / AGENT_BUSY 三场景的 client 文案与按钮行为对齐。
|
|
22
|
+
- **client 多文件化**(R1):`src/client/` 源码 + esbuild 打包(产物 `lib/client.js` 随源码提交),CI 钉产物新鲜度(F-G6)。
|
|
23
|
+
- **Host 路由域拆分**(R2):routes-core / routes-manage / session-info 三域,全部 API 可直调。
|
|
24
|
+
- **fork lineage 持久化**(F1):lineage.json 记录撤回链(childId↔parentId),快照管理按链分组展示。
|
|
25
|
+
- **verify-host 装配门禁**(E1):复刻生产装配做结构断言(兄弟提供者桩 + agents 行为),装配回归发版前即可拦截。
|
|
26
|
+
- **环境错误分类与可行动提示**(M1):快照失败按 git 缺失 / 磁盘满 / 无权限 / 锁冲突 / mkdir 冲突分类,toast 与设置页「最近错误」共用同一套可行动中文文案(≤140 字符、不含原始路径);同一错误相邻重复合并 ×N 计数。
|
|
27
|
+
- **POSIX home 三档回退与旧容器迁移**(M2):bash `$DSH_HOME` → Node `DSH_HOME` → `~/.dsh`(第三档补齐 `.dsh` 层,修复快照误落 `~/dsh-recall-snapshots` 的 I24 漂移);旧根级容器首次启动整容器自动迁移(MIGRATE_OK / OLD_ABSENT / BOTH_PRESENT / MIGRATE_FAIL 四态,数据不丢永远优先于路径规范)。
|
|
28
|
+
- **并发治理**(M3):store 心跳文件(宿主 PID + epoch 秒,随每次快照/建库刷新);失败清扫三级让路——另一活实例使用中让路(`CLEANUP_OTHER_INSTANCE`,win32 `Get-Process` / POSIX `kill -0` 探活)→ 5 分钟内新锁让路(`CLEANUP_SKIPPED_FRESH_LOCK`)→ 照常清扫(`CLEANUP_DONE`),根治 issue #11 双实例互踩死循环。
|
|
29
|
+
|
|
30
|
+
### 修复
|
|
31
|
+
|
|
32
|
+
- **PS 5.1 降级环境读编码**:index.json/lineage.json 读取显式 `-Encoding UTF8`——pwsh-local 解析链降级到 PS 5.1 时按 ANSI 活动代码页解码无 BOM UTF-8,中文 root 乱码 → 好索引被误判 corrupt 隔离(双平台实弹复现)。
|
|
33
|
+
- **双实例并发写索引的 tmp-rename 竞态**:并发 saveIndex 时一方 rename 把 `.tmp` 消费掉,另一方报「No such file」刷错误——写侧完整成功后 rename 阶段的 ENOENT 视同成功(同伴已原子落盘),不再进用户错误列表(WSL2 双实例实弹复现)。
|
|
34
|
+
- **冷启动首消息快照丢失**(ensureGit init 竞态):首条消息与启动预热并发时两个 `git init` 同跑,输家 `fatal: cannot mkdir: File exists`——POSIX 版改为 HEAD 复查放行同伴、真失败带诊断退出(WSL2 实弹复现)。
|
|
35
|
+
- **孤儿重建条目 time=0**:重建快照时间从 tag creatordate 恢复——此前重建后管理列表时间前缀缺失、retention/条数上限按「最旧」误清真实快照。
|
|
36
|
+
- **救援链路前缀契约**(F-S1,严重):rescue tag 忘拼 `snap-` 前缀导致 reset 目标必然 unknown revision、救援 100% 走失败分支——修复后救援首次真正生效(实弹验证含空格路径)。
|
|
37
|
+
- 其余审查修复:rebuildOrphans 过滤安全 tag(F-G1)、POSIX rollback 删除侧 rm 失败响亮退出(F-G2)、loadIndex 读截断与损坏区分(F-G3)、errors 测试门禁补强(F-G4)、verify-host 复刻生产装配(F-G5)、产物新鲜度 CI 门禁(F-G6)及 A1-A8 改进项。
|
|
38
|
+
|
|
39
|
+
## [2.0.0] - 2026-08-26
|
|
40
|
+
|
|
41
|
+
P0 防线(撤回防护/时效校验)、P1 工程化(单测/探针/CI)、设置页体验改造与新增四项配置、转向指令消息撤回修复。发版前活体冒烟(浏览器自动化 + 真实 dsh web)通过。
|
|
42
|
+
|
|
43
|
+
### 新增
|
|
44
|
+
|
|
45
|
+
- **运行中撤回防护**(P0-1):目标工作区 agent 正在运行时拒绝发起撤回(preview/execute 均拦截,同会话优先、快照存在时叠加跨会话同工作区检查)——避免用户确认时文件被 agent 改动,预览清单与实际回退内容脱节。拦截依赖 `inject` 声明 `agents` 服务(cordis 4 门禁,冒烟实证:漏声明时静默 fail-open,防护等于没有)。
|
|
46
|
+
- **回退时效校验**(P0-3):preview 之后、execute 之前若该消息又出现了新快照(`previewTotal` 与当前 `recall.total` 不一致),强制重新预览并提示,防止按旧清单回退。
|
|
47
|
+
- **工程化基建**(P1):vitest 单元测试(104 例)+ 官方 API 字段探针(`npm run test:probe`,dsh 升级后本地必跑)+ GitHub Actions CI;快照失败反馈持久化(设置页可回溯最近错误);per-workspace 快照条数硬上限(超出先清最旧)。
|
|
48
|
+
- **新增配置项**:快照总开关 `snapshotEnabled`(关闭只冻结新建、存量快照仍可撤回)、撤回后归档开关 `archiveOriginal`(关闭时原会话保留在侧栏)、按时间保留 `retentionDays`(0 关闭;超期快照自动清理,与条数上限独立触发)。
|
|
49
|
+
- **配置一键恢复默认**:设置页「恢复默认」走官方 `settings.replace` reset 通道(`section: {}` 重置为组合默认并清 user 覆盖层),老版本服务无该 RPC 时降级写默认值。
|
|
50
|
+
- **设置页体验改造**:文件大小上限改 MB 单位输入;快照树「加载更多」与计数修复(缓存全量数组、按 limit 切片);存储健康状态行;快照搜索框;危险操作分级(全删/清空折叠 + 二次确认);操作成功即时反馈;空态引导;「最近错误」可一键清空。
|
|
51
|
+
|
|
52
|
+
### 修复
|
|
53
|
+
|
|
54
|
+
- **转向指令消息缺撤回按钮**:agent 运行中插入的用户输入在 UI 投影层为 `kind=steering`(存储层 `role` 恒 user、无差异),不命中 keyed `user` 渲染器而落到官方默认气泡——keyed 注册扩展为 `['user','steering']`(冒烟实测复现并验证)。
|
|
55
|
+
|
|
22
56
|
## [1.7.1] - 2026-08-25
|
|
23
57
|
|
|
24
58
|
### 修复
|
|
25
59
|
|
|
26
60
|
- 历史会话中用户消息图片从未渲染([#9](https://github.com/limbo947/dsh-recall-plugin/issues/9)):插件渲染器读取的 `props.loadImage` 在官方 `conversation.chat.node` slot 契约中**从不存在**(实际入口是 `props.renderMessageImages`),自研加载链在守卫处直接 return——v1.6.2 的重试链、v1.7.0 的失败按钮全部从未执行,图片永久无声空白(v1.6.2/#8 的修复因此「修了却无效」)。用户消息图片改走官方 `renderMessageImages` 管线(自带鉴权、缓存、失败重试与灯箱预览),布局对齐官方(图片在上、气泡在下);自研 `ImageBox`/`useImageSrc` 及对应 CSS 作为死代码移除。
|
|
27
61
|
|
|
28
|
-
## [1.7.0] - 2026-08-25
|
|
29
|
-
|
|
30
|
-
### 新增
|
|
31
|
-
|
|
32
|
-
- 快照失败/跳过可见性([#7](https://github.com/limbo947/dsh-recall-plugin/issues/7) 加固项 1):快照失败或熔断时客户端 toast 提示(同一故障文本 10 分钟节流,避免持续故障期间刷屏),轮询到失败即终止、不再空等 20 次;熔断期间的新消息会收到「已暂停,N 分钟后自动重试」提示而非沉默。「按钮为什么消失了」的排障成本由此消掉。
|
|
33
|
-
- `git add --ignore-errors` fail-open 兜底([#7](https://github.com/limbo947/dsh-recall-plugin/issues/7) 加固项 3):无法索引的路径(无提交的嵌入式仓库、不可读文件等)以退出码 1 结束但索引照常落盘——快照缺个别路径可接受,好过整条快照 fatal。被跳过的路径以 SNAP_SKIP 行回传,客户端提示「快照已跳过未纳入的路径」(这些路径撤回时既不恢复也不会被删,与排除表语义一致)。
|
|
34
|
-
- 失败后孤儿进程清扫 + stale 锁清理([#7](https://github.com/limbo947/dsh-recall-plugin/issues/7) 加固项 4):runShell 失败路径按 `--git-dir=<本仓库>` 命令行标记定位漏网孤儿进程并终止(win: `taskkill /T /F`,POSIX: `pgrep`+`kill`),随后清理 index.lock 等残留锁——DSH subprocess 服务的树级终止有竞态窗口,且 git 被硬杀不做锁回收,残留的 index.lock 会让后续每条快照持续 fatal。
|
|
35
|
-
|
|
36
|
-
### 修复
|
|
37
|
-
|
|
38
|
-
- `git add` fatal 时脚本假成功(空树快照):pwsh 对原生命令非零退出不抛错(ErrorActionPreference 不作用于 native),此前 add fatal 后脚本会带着未更新的旧索引继续走完 write-tree/commit/tag,产出空树 tag 且退出码 0——快照「成功」却什么都回退不了。现显式检查退出码(≥2 抛错终止),diff/rollback 的同款 add 一并修复。
|
|
39
|
-
|
|
62
|
+
## [1.7.0] - 2026-08-25
|
|
63
|
+
|
|
64
|
+
### 新增
|
|
65
|
+
|
|
66
|
+
- 快照失败/跳过可见性([#7](https://github.com/limbo947/dsh-recall-plugin/issues/7) 加固项 1):快照失败或熔断时客户端 toast 提示(同一故障文本 10 分钟节流,避免持续故障期间刷屏),轮询到失败即终止、不再空等 20 次;熔断期间的新消息会收到「已暂停,N 分钟后自动重试」提示而非沉默。「按钮为什么消失了」的排障成本由此消掉。
|
|
67
|
+
- `git add --ignore-errors` fail-open 兜底([#7](https://github.com/limbo947/dsh-recall-plugin/issues/7) 加固项 3):无法索引的路径(无提交的嵌入式仓库、不可读文件等)以退出码 1 结束但索引照常落盘——快照缺个别路径可接受,好过整条快照 fatal。被跳过的路径以 SNAP_SKIP 行回传,客户端提示「快照已跳过未纳入的路径」(这些路径撤回时既不恢复也不会被删,与排除表语义一致)。
|
|
68
|
+
- 失败后孤儿进程清扫 + stale 锁清理([#7](https://github.com/limbo947/dsh-recall-plugin/issues/7) 加固项 4):runShell 失败路径按 `--git-dir=<本仓库>` 命令行标记定位漏网孤儿进程并终止(win: `taskkill /T /F`,POSIX: `pgrep`+`kill`),随后清理 index.lock 等残留锁——DSH subprocess 服务的树级终止有竞态窗口,且 git 被硬杀不做锁回收,残留的 index.lock 会让后续每条快照持续 fatal。
|
|
69
|
+
|
|
70
|
+
### 修复
|
|
71
|
+
|
|
72
|
+
- `git add` fatal 时脚本假成功(空树快照):pwsh 对原生命令非零退出不抛错(ErrorActionPreference 不作用于 native),此前 add fatal 后脚本会带着未更新的旧索引继续走完 write-tree/commit/tag,产出空树 tag 且退出码 0——快照「成功」却什么都回退不了。现显式检查退出码(≥2 抛错终止),diff/rollback 的同款 add 一并修复。
|
|
73
|
+
|
|
40
74
|
## [1.6.2] - 2026-08-25
|
|
41
75
|
|
|
42
76
|
### 修复
|
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|

|
|
9
9
|

|
|
10
10
|

|
|
11
|
-

|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
**Under any message you've sent**, **click "↶ Recall"**, **and both your workspace files and the conversation history roll back to the moment right before that message was sent**.
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
- Supports Windows (PowerShell 5.1/7 + git CLI) and Linux/macOS (bash + git CLI). Windows is thoroughly verified on real machines; Linux has been fully tested on WSL2 (Ubuntu 26.04, bash 5.3 + git 2.53), including Chinese paths, home fallback, session cleanup, and gc; the macOS side is written to be bash 3.2 compatible but has not been tested on real hardware yet.
|
|
56
56
|
- Nested git repositories inside the workspace (subdirectories with their own `.git`) cannot be indexed: the snapshot proceeds for everything else (fail-open, with a toast listing the skipped paths), but their contents do not participate in recalls.
|
|
57
57
|
- Extreme cases like filenames containing newlines/TAB are beyond the diff list's parsing capability (negligible probability).
|
|
58
|
+
- **Interplay with dsh-routing-suite (progressive tool-disclosure router)**: if you also run the router-standard preset, a recall forks a new session via `sessions.fork`, which resets the router's stage to its default (the tool surface temporarily narrows). Symptoms, root cause and the fix are documented in [docs/routing-interplay.md](docs/routing-interplay.md) (Chinese).
|
|
58
59
|
|
|
59
60
|
## Installation
|
|
60
61
|
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|

|
|
6
6
|

|
|
7
7
|

|
|
8
|
-

|
|
9
9
|
|
|
10
10
|

|
|
11
11
|

|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
- 支持 Windows(PowerShell 5.1/7 + git CLI)与 Linux/macOS(bash + git CLI)。Windows 真机验证充分;Linux 已在 WSL2(Ubuntu 26.04,bash 5.3 + git 2.53)实测全流程(含中文路径、home 降级、会话清理、gc);macOS 侧脚本按 bash 3.2 兼容编写,尚未真机实测。
|
|
54
54
|
- 工作区内嵌套的其他 git 仓库(子目录自带 `.git`)无法索引:快照对其余部分照常(fail-open,页面会提示跳过了哪些路径),但其内容不参与回退。
|
|
55
55
|
- 文件名含换行/TAB 的极端情形不在 diff 清单的解析能力内(概率可忽略)。
|
|
56
|
+
- **与 dsh-routing-suite(渐进式工具披露路由)的交互**:若同时启用 dsh-routing-suite 的 router-standard 预设,撤回会经 `sessions.fork` 出新会话,导致路由阶段重置为默认(工具面临时收窄)。现象、成因与解决方案见 [docs/routing-interplay.md](docs/routing-interplay.md)。
|
|
56
57
|
|
|
57
58
|
## 安装
|
|
58
59
|
|