dsh-rewind-plugin 0.9.0-alpha.2 → 0.10.0-alpha.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/README.en.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # dsh-rewind
2
2
 
3
3
  > [!WARNING]
4
- > **Planning to use DSH `0.1.3`? Upgrade to the latest plugin (`>= 0.9.0-alpha.1`) as soon as possible and run `/dsh-rewind-fix` to update old rewind markers** ([update guide](docs/rewind-fix.md)).
4
+ > **Planning to use DSH `0.1.3`? Install a `v0.9.x` release as soon as possible and run `/dsh-rewind-fix` to update old rewind markers** ([update guide](docs/rewind-fix.md)).
5
5
 
6
6
  Conversation rewind for DeepSeek Harness: **rewind the conversation to any earlier user message in one click, in the same window** — no new branch, no window switch, with optional workspace-file restore (full Claude Code `/rewind` semantics).
7
7
 
@@ -106,7 +106,7 @@ The whole design rests on two principles, simple but deliberate: **the conversat
106
106
 
107
107
  The file half follows Claude Code's checkpoint semantics — **partial tracking + before-write backup, plus a re-scan of tracked files at each message**, not a whole-tree snapshot. This trade-off saves space, and it's actually more complete:
108
108
 
109
- - **Before-write backup**: tracks only the write-class tools (`write`, `edit`, `str_replace_editor`) — backs up the original content before a write and records/tracks the files it touches; it never backs up the whole workspace, so it's lightweight.
109
+ - **Before-write backup**: tracks only the write-class tools (`write`, `edit`) — backs up the original content before a write and records/tracks the files it touches; it never backs up the whole workspace, so it's lightweight.
110
110
  - **External changes count too**: at every user-message boundary the plugin re-checks all tracked files — external changes such as a command run or a manual edit are recorded as well and restored by a later rewind. "Lightweight" but not "incomplete".
111
111
  - **Unchanged-not-recorded, identical-content-as-link**: an entry is written only when something changed — at the message-boundary re-check, an unchanged file is never backed up (no record); at before-write time, when the new content matches the path's prior record, only a **link to it** (`ref`) is stored instead of a copy. Repeated writes cost almost nothing, and a link is materialized before its group is evicted — never left dangling.
112
112
  - **Reconcile against the real disk before restoring**: restore takes each path's **earliest** record, then reads the live file and compares — **only files that actually differ are touched**: modified files are written back to the earliest backup, files created after the target are deleted, already-matching files are skipped. Repeated rewinds are therefore **idempotent with zero side effects** and never produce "ghost impact".
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # dsh-rewind
2
2
 
3
3
  > [!WARNING]
4
- > **计划使用 DSH `0.1.3` 的用户:请尽早升级到最新插件(`>= 0.9.0-alpha.1`),并运行 `/dsh-rewind-fix` 更新旧回退标记**([更新指南](docs/rewind-fix.zh.md))。
4
+ > **计划使用 DSH `0.1.3` 的用户:请尽早安装 `v0.9.x` 版本,并运行 `/dsh-rewind-fix` 更新旧回退标记**([更新指南](docs/rewind-fix.zh.md))。
5
5
 
6
6
  DeepSeek Harness 插件:**一键就地回退对话到任意更早的用户消息**——同窗口内完成,不新建分支、不换窗口,可一并还原工作区文件(完整 Claude Code `/rewind` 语义)。
7
7
 
@@ -96,7 +96,7 @@ dsh plugin --profile web add dsh-rewind-plugin
96
96
 
97
97
  文件部分对齐 Claude Code 的检查点语义——**局部追踪、写前备份 + 每条消息重扫已跟踪文件**,而不是整树快照。这项取舍既省空间,又更完整:
98
98
 
99
- - **写前备份**:只追踪写类工具(`write`、`edit`、`str_replace_editor`),写前**备份原内容**,并**记录、追踪**被处理的文件——从不备份整个工作区,因此轻量。
99
+ - **写前备份**:只追踪写类工具(`write`、`edit`),写前**备份原内容**,并**记录、追踪**被处理的文件——从不备份整个工作区,因此轻量。
100
100
  - **外部变更也追**:每条用户消息边界,插件重新检查所有已跟踪文件——命令执行、手动修改等外部变更同样被记录,回退时一并还原。这让「轻量」却不「残缺」。
101
101
  - **不变不存、同内容存链接**:记录只在有变化时发生——消息边界重扫时无变更的不备份(不留记录);写前备份时若与前一条记录一致,只存**指向它的链接**(`ref`)而非复制内容。重复写入几乎不占空间,链接也先落地、绝不悬空。
102
102
  - **还原时对照真实磁盘**:先取每条路径的**最早**记录,再实时读取文件当前内容与之比对——**只操作真正不一致的文件**:改过的写回最早期内容、目标之后新建的删除、已经一致的跳过。重复回退因此**零副作用、幂等**,不会出现「幽灵影响」。
@@ -17,12 +17,9 @@ credentials access.
17
17
 
18
18
  ```
19
19
  src/
20
- ├── index.ts host plugin: /rewind, /undo, /snapshot-auto-cleanup,
21
- /dsh-rewind-fix commands + checkpoint pipeline
20
+ ├── index.ts host plugin: /rewind, /undo, /snapshot-auto-cleanup
21
+ │ commands + checkpoint pipeline
22
22
  ├── rewind.ts pure planning: target parsing, surface-range plan, candidate listing
23
- ├── rewind-fix.ts /dsh-rewind-fix orchestration (repair pipeline, locks, rollback)
24
- ├── rewind-marker-repair.ts pure legacy-marker transform (A/B → C)
25
- ├── session-log-io.ts session-log zstd codec + lossless re-encoder (rewind-fix write-back)
26
23
  ├── snapshot.ts checkpoint store: disk before-backups, journaled restore,
27
24
  │ reconcile / continue / rollback, bounded prune
28
25
  ├── snapshot-cleanup.ts cleanup policy + dsh-settings persistence + auto-sweep throttle
@@ -33,6 +30,11 @@ src/
33
30
  pending interaction, locales, styles
34
31
  ```
35
32
 
33
+ The old marker-update repair line (`/dsh-rewind-fix` and its `rewind-fix.ts` /
34
+ `rewind-marker-repair.ts` / `session-log-io.ts` modules) was a **temporary
35
+ migration tool** for the DSH `0.1.2-rc.1` → `0.1.3` transition: it shipped
36
+ through the `0.9.x` line and is **removed in the `0.10.x` line**.
37
+
36
38
  Two dependency rules keep the design testable:
37
39
 
38
40
  1. **`rewind.ts` is pure** — no I/O, no `Session` dependency; everything
@@ -89,13 +91,15 @@ plugin versions wrote shapes a newer harness no longer accepts:
89
91
  inside a closed turn.
90
92
 
91
93
  A/B became unreadable once v2 reserved surface `replace` to a node that cites
92
- `sourceEventSeqs` (`assistant/message` can no longer carry them). `/dsh-rewind-fix`
93
- rewrites form A/B in closed sessions to form C so a newer harness accepts the log.
94
+ `sourceEventSeqs` (`assistant/message` can no longer carry them). The
95
+ `/dsh-rewind-fix` command rewrote form A/B in closed sessions to form C so a
96
+ newer harness accepts the log — it was a **temporary migration tool** (kept on
97
+ the `0.9.x` line) and is **removed in the `0.10.x` line**.
94
98
 
95
99
  ## Checkpoint pipeline (Claude Code before-backup model)
96
100
 
97
101
  ```
98
- tools/execute captureBefore: for write / edit / str_replace_editor
102
+ tools/execute captureBefore: for write / edit
99
103
  (mutating commands only), read the file's BEFORE state;
100
104
  subagent edits are NOT tracked (Claude Code alignment).
101
105
  tools/post-execute commitEntry: anchor = latest user/message seq; skip
package/docs/format.md CHANGED
@@ -158,8 +158,7 @@ Old-format data is never silently re-interpreted.
158
158
  The snapshot auto-cleanup policy (the `enabled` switch and the `maxAgeDays`
159
159
  idle cutoff) is no longer a file: it lives in the **dsh-settings document** under
160
160
  the `dsh-rewind-snapshot-cleanup` namespace (validated by a schemastery schema;
161
- defaults are the `base` layer). On first run after this change, a legacy
162
- `<dsh home>/snapshot-cleanup.json` is imported into the document **once** and
163
- then deleted (an absent file is a no-op; an invalid file imports the safe
164
- default and is dropped). The last-sweep clock stays in its own
161
+ defaults are the `base` layer). The policy was previously persisted in a legacy
162
+ `<dsh home>/snapshot-cleanup.json` file; that file store and its one-time
163
+ startup migration have been removed. The last-sweep clock stays in its own
165
164
  `<dsh home>/snapshot-cleanup-last-sweep.json` state file, which is unchanged.
@@ -49,12 +49,9 @@ the canonical source; this block only adds the finer-grained client-side files
49
49
  and packaging entries.
50
50
 
51
51
  ```
52
- src/index.ts host plugin: /rewind|/undo|/snapshot-auto-cleanup|/dsh-rewind-fix
52
+ src/index.ts host plugin: /rewind|/undo|/snapshot-auto-cleanup
53
53
  + checkpoint pipeline (tools/execute|post-execute)
54
54
  src/rewind.ts pure planning: target resolution, surface range, candidate listing
55
- src/rewind-fix.ts /dsh-rewind-fix orchestration (repair pipeline, locks, rollback)
56
- src/rewind-marker-repair.ts pure legacy-marker transform (A/B → C)
57
- src/session-log-io.ts session-log zstd codec + lossless re-encoder (rewind-fix write-back)
58
55
  src/snapshot.ts checkpoint store (disk before-backups, restore/preview, bounded prune)
59
56
  src/snapshot-cleanup.ts cleanup policy + dsh-settings persistence + auto-sweep throttle
60
57
  src/session-cwd.ts session-cwd resolution (fs-tools rule)
@@ -5,7 +5,7 @@
5
5
  ## Applies to
6
6
 
7
7
  - **DSH**: `0.1.2-rc.1`
8
- - **dsh-rewind**: `0.9.0-alpha.1`
8
+ - **dsh-rewind**: `0.9.0-alpha.1`, `0.9.0-alpha.2`, `0.9.0`
9
9
 
10
10
  ## Background
11
11
 
@@ -40,7 +40,7 @@ The command rewrites session files and clears some snapshots, so a backup is a g
40
40
  cp -r ~/.dsh/sessions ~/.dsh/sessions.backup
41
41
  cp -r ~/.dsh/rewind-snapshots ~/.dsh/rewind-snapshots.backup
42
42
  ```
43
- Or copy them anywhere convenient.
43
+ Or copy them anywhere convenient. You can also let the AI run the backup for you.
44
44
 
45
45
  ### Step 3 · Start a new session, or pick one that was never rewound
46
46
 
@@ -50,11 +50,11 @@ The command only handles **closed** sessions, and it can't run on itself. So:
50
50
 
51
51
  Then run the command **in this new session**, and it will update the old sessions that need it.
52
52
 
53
- > ⚠️ Don't run it in a session that itself needs updating and is currently open — the command skips this session, and any other currently-open/in-use session.
53
+ > Don't run it in a session that itself needs updating and is currently open — the command skips this session, and any other currently-open/in-use session.
54
54
 
55
55
  ### Step 4 · Preview the update scope
56
56
 
57
- Type `/dsh-rewind-fix` in the composer and send it. It only scans, doesn't write it reports how many sessions were scanned, how many will be updated, how many skipped, and how many failed. Confirm those are what you expect before moving on.
57
+ Type `/dsh-rewind-fix` in the composer and send it. It only scans, doesn't write. The editor locks while it runs, which is normal. **Don't switch session windows midway.** When it finishes, it reports how many sessions were scanned, how many will be updated, how many skipped, and how many failed. Confirm those are what you expect before moving on.
58
58
  ```
59
59
  /dsh-rewind-fix
60
60
  ```
@@ -67,7 +67,7 @@ Once you're sure, re-enter the command with `--apply` to actually run it:
67
67
  ```
68
68
  This really rewrites the session logs and updates the old markers, and **may take a few minutes**. Please let it finish — **don't switch to another session window or close DSH** while it runs: a session you switch to is **safely skipped** (no corruption, but it won't be updated this pass and you'll need to re-run). A session that fails stays as it was, unharmed, and can be updated again later. Sessions that are updated also get their matching **snapshot backups cleared**, so file restore to earlier messages is no longer available for them.
69
69
 
70
- ### Step 6 · Restart DSH and preview again (optional)
70
+ ### Step 6 · Restart DSH and preview again
71
71
 
72
72
  After the run, restart DSH, then **preview once more**:
73
73
  ```
@@ -4,8 +4,8 @@
4
4
 
5
5
  ## 适配
6
6
 
7
- - **DSH**:`0.1.2-rc.1`
8
- - **dsh-rewind**:`0.9.0-alpha.1`
7
+ - **DSH**: `0.1.2-rc.1`
8
+ - **dsh-rewind**: `0.9.0-alpha.1`, `0.9.0-alpha.2`, `0.9.0`
9
9
 
10
10
  ## 背景
11
11
 
@@ -40,7 +40,7 @@
40
40
  cp -r ~/.dsh/sessions ~/.dsh/sessions.backup
41
41
  cp -r ~/.dsh/rewind-snapshots ~/.dsh/rewind-snapshots.backup
42
42
  ```
43
- 或者复制到任意合适的位置。
43
+ 或者复制到任意合适的位置。你也可以直接让 AI 帮你完成数据的备份。
44
44
 
45
45
  ### 第三步 · 新建会话,或选一个从未回退过的会话
46
46
 
@@ -50,11 +50,11 @@ cp -r ~/.dsh/rewind-snapshots ~/.dsh/rewind-snapshots.backup
50
50
 
51
51
  然后在**这个新会话窗口里**运行命令,去更新那些需要处理的旧会话。
52
52
 
53
- > ⚠️ 别在「本身就需要更新、且正开着」的会话里运行——命令会跳过本会话,以及任何正被打开/使用的会话。
53
+ > 别在「本身就需要更新、且正开着」的会话里运行——命令会跳过本会话,以及任何正被打开/使用的会话。
54
54
 
55
55
  ### 第四步 · 预览更新范围
56
56
 
57
- 在编辑区域输入 `/dsh-rewind-fix` 并发送。它只扫描、不写盘,会告诉你:扫描了几个会话、其中几个将被更新、几个跳过、几个失败。确认是你预期的那几项,再进下一步。
57
+ 在编辑区域输入 `/dsh-rewind-fix` 并发送。它只扫描、不写盘。执行时编辑区会正常锁定。**不要中途切换会话窗口。**完成后会告诉你:扫描了几个会话、其中几个将被更新、几个跳过、几个失败。确认是你预期的那几项,再进下一步。
58
58
  ```
59
59
  /dsh-rewind-fix
60
60
  ```
@@ -67,7 +67,7 @@ cp -r ~/.dsh/rewind-snapshots ~/.dsh/rewind-snapshots.backup
67
67
  ```
68
68
  这一步会真的改动会话日志、把旧标记更新成新格式,**可能需要几分钟**。请耐心等它跑完,**不要中途切换会话窗口**或关闭 DSH——被切到的会话会被**安全地跳过**(不损坏,但这次不会更新,需重新执行)。更新失败的会话保持原状态不变、无破坏,可重新进行更新。被更新的会话会同时**清掉对应的文件快照备份**,更早消息回退时文件还原不可用。
69
69
 
70
- ### 第六步 · 重启 DSH,再预览确认(可选)
70
+ ### 第六步 · 重启 DSH,再预览确认
71
71
 
72
72
  执行完后重启一下 DSH,然后**再跑一次预览**:
73
73
  ```
package/lib/client.js CHANGED
@@ -446,7 +446,12 @@ var STYLE = `
446
446
  line-height: 1.5;
447
447
  color: var(--dsw-alias-label-error);
448
448
  }
449
- /* Switch row: label left, role=switch button right, hint below (Subagent module). */
449
+ /* Switch row: label left, role=switch button right, hint below (Subagent module).
450
+ * The track mirrors the harness ui-primitives Switch (0.1.3-alpha.2 line): the
451
+ * on/off appearance keys off aria-checked rather than a parallel class, so the
452
+ * visual state cannot disagree with the state assistive technology reads, and
453
+ * corner-shape: round opts the capsule track out of the global superellipse
454
+ * (which would square the capsule ends off against the round thumb inside). */
450
455
  .dsh-rewind-cleanup-toggle-row {
451
456
  display: flex;
452
457
  align-items: flex-start;
@@ -469,10 +474,11 @@ var STYLE = `
469
474
  padding: 2px;
470
475
  border: 0;
471
476
  border-radius: 10px;
477
+ corner-shape: round;
472
478
  background: var(--dsw-alias-border-l3);
473
479
  cursor: pointer;
474
480
  }
475
- .dsh-rewind-cleanup-switch-on {
481
+ .dsh-rewind-cleanup-switch[aria-checked='true'] {
476
482
  background: var(--dsw-alias-brand-primary);
477
483
  }
478
484
  .dsh-rewind-cleanup-switch:disabled {
@@ -492,7 +498,7 @@ var STYLE = `
492
498
  background: var(--dsw-alias-label-primary-foreground);
493
499
  transition: transform 120ms ease;
494
500
  }
495
- .dsh-rewind-cleanup-switch-on .dsh-rewind-cleanup-thumb {
501
+ .dsh-rewind-cleanup-switch[aria-checked='true'] .dsh-rewind-cleanup-thumb {
496
502
  transform: translateX(16px);
497
503
  }
498
504
  .dsh-rewind-cleanup-input {
@@ -1333,8 +1339,8 @@ function createRewindBridge(deps) {
1333
1339
  }
1334
1340
 
1335
1341
  // src/client/build-info.ts
1336
- var PLUGIN_VERSION = true ? "0.9.0-alpha.2" : "dev";
1337
- var BUILD_HASH = true ? "ca24fc4e" : "dev";
1342
+ var PLUGIN_VERSION = true ? "0.10.0-alpha.1" : "dev";
1343
+ var BUILD_HASH = true ? "7022eaa4" : "dev";
1338
1344
 
1339
1345
  // src/client/locales.ts
1340
1346
  var zh = {
@@ -1531,7 +1537,7 @@ function SettingsCleanupCard({ api, t }) {
1531
1537
  {
1532
1538
  type: "button",
1533
1539
  role: "switch",
1534
- className: `dsh-rewind-cleanup-switch${draft.enabled ? " dsh-rewind-cleanup-switch-on" : ""}`,
1540
+ className: "dsh-rewind-cleanup-switch",
1535
1541
  "aria-checked": draft.enabled,
1536
1542
  "aria-labelledby": "dsh-rewind-cleanup-enabled-label",
1537
1543
  disabled,