• v1.4.0 5511091cd3

    wqmll released this 2026-10-18 23:27:25 +08:00 | 0 commits to main since this release

    1.4.0 — 借 IG5 的做法加固四处工程细节

    参考 Minglink/dsh-infinite-gen-5 的 source/json_output.js、source/attachment_lease.js、审批门与 CAS 修订号模式,挑了四处与本插件能力相符的改进。不搬它的逆向引擎、worker 协议、Ghidra / x64dbg 适配层——那些属于另一类插件。

    新增:严格 JSON 输出边界(lib/json-safe.js)

    宿主会在渲染前校验工具结果。旧实现全程 JSON.stringify,三种情况会出事:

    情况 旧行为 现在
    BigInt(如 64 位地址被算成 BigInt) 抛异常 → 整个响应 500 投影阶段报 INVALID_PLUGIN_OUTPUT 并指出路径
    循环引用 抛异常 → 500 同上,带 at 定位
    字段值 undefined 静默丢字段 → 界面以为「没数据」 省略该字段但保留 null;不可靠值转成 {__invalid,__reason,__at}

    另外拒绝 -0、NaN、Infinity、Symbol、Function、稀疏数组、带额外属性的数组、accessor、非普通对象(class 实例)。深度上限 64、节点上限 20 万,超限报错而非截断。64 位地址保持字符串精度。

    sendJson 全部改走 stringifySafe —— 永不抛,坏字段变成可诊断标记,而不是把 200 变成 500。

    新增:文件身份与写入守卫(lib/host-lease.js)

    改宿主文件之前要先确认「我改的还是我看到的那个文件」。旧实现只比路径字符串,三种情况会被骗:

    1. 目标被换成符号链接 / 目录联接 → 看到的是另一份文件;
    2. 同一路径下文件被替换(重装、换版本)→ 路径对、内容不对;
    3. Windows 路径大小写不敏感,C:\App 与 c:\app 会被当成两份。

    现在写前取一份 identity(真实路径 + size + mtime + 前 64 KiB 的 SHA-256),写完再取一次,不一致报 changed / vanished。另附 writeFileAtomic(同目录临时文件 → rename),保留原文件 mode。

    新增:审批档位与审计流水(lib/tool-gate.js)

    purge_apply / purge_revert / purge_uninstall 三个破坏性工具以前没有任何「这次调用批没批」的记录。现在:

    • 审计永远记:$DSH_HOME/dsh-purge/audit.jsonl,每次调用一行(intent / allow / deny / result),失败也记;审计写不进去绝不影响工具结果。
    • 审批可选,approvalMode 两档:
      • audit(默认):只记流水,行为与旧版完全一致,不弹任何东西。
      • enforce:走宿主 approval.request,只有明确 allowed-once 才 next()。缺 agent、缺 approval 服务、抛错、未知结果、signal 已 abort —— 一律 deny 不派发,从不缓存上一次批准。

    默认不是 enforce 的原因:本插件的主入口是人自己点「应用」,人就是审批者,再弹一次只是多一次点击;而本机策略可能把 approval 一律自动拒绝,强制审批等于把插件锁死。需要更严时(模型自动跑长任务)再切 enforce。

    • 新工具 purge_audit:读回审计尾部,让模型在长任务里能自查「上一次 apply 到底批没批、结果如何」。
    • 设置页新增「审批与审计」区块:单选档位 + 展开查看流水(.dshp-audit,等宽、限高滚动)。

    新增:状态修订号(lib/revision.js)

    设置页每 5 秒轮询 /status,Web 与桌面可能同时开着。旧实现里 apply / revert 无条件执行,后点的会静默覆盖先点的结果。

    现在状态机有单调递增的 rev:/status 带出,动作时带回,不一致返回 409 + 当前 rev + 最后一次动作。客户端收到 409 提示「另一个窗口刚改过状态」并自动重新拉取,而不是留着旧数字让用户重复点击。不持久化——重启后归零是正确语义。

    修复:hooksDenyBypass 保存时抹掉同文件其他键

    saveHookDenySettings 原来只重建 hooksDenyBypass 一个键再覆盖整文件。approvalMode 住进同一个 hooks-deny.json 后,切一次 hooks 开关就会把审批档位悄悄重置。改成合并写入(实测:approvalMode 与 hooksDenyBypass 同时保留)。

    优化:请求体错误分类

    readJsonBody 原来只抛一句 Error,所有异常都压成 500,界面无法区分「内容太大」和「JSON 写错了」。现在按 BODY_TOO_LARGE(413)、BODY_INVALID_JSON(400)、BODY_NOT_OBJECT(400)分类,19 处 catch 统一走 bodyErrorStatus。

    新增接口

    路由 方法 作用
    /dsh-purge/approval-mode GET / POST 读/写审批档位,重启后生效
    /dsh-purge/audit GET 读审计尾部(?limit=1..200,默认 40)

    /dsh-purge/status 新增 rev、last_action、approval_mode 三个字段。

    测试

    71 项离线断言(json-safe 20 / host-lease 13 / revision 11 / tool-gate 27),不启动宿主、不碰真实工程。



    镜像说明 / Mirror note:dsh-purge-plus 是社区分支(JeffKeeping/dsh-purge-plus),不在已删除的 YuJunZhiXue/dsh-purge 仓库内,原仓库没有发布过 GitHub Release。本 Release 由镜像仓库 wqmll/dsh-purge-plus 依据 tag 生成,说明文字取自该分支的 CHANGELOG.md。

    资产按上游 CI 相同方式生成:dsh-purge-plus-1.4.0.zip 是 git archive 源码包(可直接 dsh plugin install 离线安装);dsh-purge-plus-1.4.0.tgz 是内容等价的 npm 包。

    Downloads