Skip to content

BeforeWrite v5.0.0 — 图形时间轴:一条时间轴,点一下就回到那一刻

Choose a tag to compare

@caishengshuo caishengshuo released this 24 Oct 22:32
· 12 commits to main since this release

BeforeWrite v5.0.0 — 有界面了:一条时间轴,点一下就回到那一刻

这一版把 BeforeWrite 从「只能命令行查」变成「打开就能看、点一下就能退」。

新增

图形时间轴(界面半边 client.js)

  • 界面右上角(顶栏下方)多一个 ⏱ 时光机 按钮,点开是全屏面板。
  • 左栏:这台机器上跑过的每个会话,带「最后活动时间 / 事件数 / 台词数 / 快照数」,点一个切一条时间轴。
  • 右栏:该会话的完整时间轴,按时间合并三类记录——
    • 说过 你在这一轮真正打出去的话(注入型上下文会被过滤,不算台词)
    • 动作 DSH 调了哪个工具、参数前 200 字
    • 快照 这一轮它改了哪个文件、多少字节
  • 每条快照右侧一个 回档 按钮,点了就把那个文件还原到那一刻;旁边的 diff 可以先看差在哪。

HTTP 接口(宿主半边自带,界面就靠它取数)

接口 作用
GET /beforewrite/api/sessions 会话列表
GET /beforewrite/api/timeline?sid=… 某会话的时间轴
GET /beforewrite/api/diff?id=… 某条快照的 diff
GET /beforewrite/api/restore?id=… 把文件还原到该快照

第 7 个动作 snapshot:给 shell 里 rm / sed -i / 重定向这类绕过文件服务的破坏性操作,提前打点。

修复(都是实测踩出来的)

  • 客户端模块 id 必须逐字等于包名,否则 __ModuleLoader__.load 报 loaded without registering,而且会拖死整个 bundle(宿主半边一起不上线)。
  • apply 执行时 ctx.get('webServer') 还是 undefined,路由挂不上 → 改成每 500ms 轮询、最多等 2 分钟。
  • require('styles') 在宿主里取不到,只靠它整块面板会变成无样式裸文字盖在对话上 → 改成自己往 document.head 插 <style>。
  • 悬浮按钮从右下角移到右上角,不再盖住 dsh-purge 的 dock 按钮。
  • 时间轴不再把注入型消息当作用户台词。

安装

# 方式一:本地目录
# 在 DSH 里执行 plugin_manager install_bundle,目标是这个目录
# 方式二:先克隆再装
git clone https://github.com/caishengshuo/beforewrite.git

装完刷新页面,右上角出现「⏱ 时光机」。

仍然有的局限

  1. 拦不住 shell —— rm、sed -i、重定向都不经过文件服务,需要手动 snapshot。
  2. 只管文本,二进制文件无法 diff。
  3. 仓库是本地的,不跨机器同步。
  4. 索引只增不减,磁盘会慢慢长。
  5. 工具名固定 time_machine,不随项目名变化。

English

BeforeWrite v5 adds a GUI: a per-session timeline (what you said / which tools ran / which files were snapshotted) with a one-click restore button on every snapshot. The timeline is fed by the host plugin's own HTTP API, and the UI half is plain JS mounted on the shell.overlay slot — no build step.

Also fixed: client module id must equal the package name (otherwise the whole bundle fails to activate), webServer is not yet available during apply (now polled), and require('styles') is unavailable in the host (styles are now injected into document.head directly).