dsh-turn-undo 0.0.3 → 0.0.4

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.
Files changed (2) hide show
  1. package/index.js +42 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1031,7 +1031,9 @@ function createHandler(ctx, runtime, sessions, agents) {
1031
1031
  // Wait for any in-flight snapshot capture so the preview reflects the
1032
1032
  // latest committed workspace state (avoids showing a stale turn/end).
1033
1033
  try { await runtime.waitForSnapshots() } catch {}
1034
- const preview = runtime.store.preview(sessionId, targetTurn)
1034
+ const source = await readSession(ctx, sessionId)
1035
+ const cwd = source ? getCwd(source) : undefined
1036
+ const preview = runtime.store.preview(sessionId, targetTurn, cwd)
1035
1037
  return json(response, 200, preview)
1036
1038
  }
1037
1039
 
@@ -1174,9 +1176,35 @@ export function apply(ctx, config = {}) {
1174
1176
  })
1175
1177
  }
1176
1178
 
1179
+ /**
1180
+ * Build a manifest from the current workspace state without persisting it.
1181
+ * Used by preview when the target turn is beyond the latest snapshot.
1182
+ */
1183
+ SnapshotStore.prototype.buildLiveManifest = function (cwd) {
1184
+ const ignore = makeIgnore(cwd, this.excludes)
1185
+ const files = this.scan(cwd, ignore)
1186
+ if (!files) return null
1187
+ const manifest = {}
1188
+ for (const p of files) {
1189
+ const abs = p
1190
+ let st
1191
+ try { st = lstatSync(abs) } catch { continue }
1192
+ if (!st.isFile()) continue
1193
+ const rel = relative(cwd, abs).split('\\').join('/')
1194
+ manifest[rel] = {
1195
+ kind: 'file',
1196
+ hash: hashFile(abs),
1197
+ size: st.size,
1198
+ mtime: st.mtimeMs,
1199
+ mode: st.mode.toString(8).padStart(4, '0'),
1200
+ }
1201
+ }
1202
+ return manifest
1203
+ }
1204
+
1177
1205
  // Add preview helper to SnapshotStore prototype.
1178
1206
  // Returns the files that changed during the target turn (turn/end vs turn/start).
1179
- SnapshotStore.prototype.preview = function (sessionId, targetTurn) {
1207
+ SnapshotStore.prototype.preview = function (sessionId, targetTurn, cwd) {
1180
1208
  const chain = this.loadChain(sessionId)
1181
1209
  if (targetTurn === null) {
1182
1210
  return { ok: true, status: 'ready', targetTurn: null, totalChanges: 0, changes: [] }
@@ -1202,7 +1230,18 @@ SnapshotStore.prototype.preview = function (sessionId, targetTurn) {
1202
1230
 
1203
1231
  // 会话最新快照 = 撤销点之后所有改动的累积终点。
1204
1232
  const latest = chain[chain.length - 1]
1205
- const latestManifest = latest.manifest
1233
+
1234
+ // If targetTurn is beyond the latest snapshot (e.g., the turn hasn't ended
1235
+ // yet or snapshots were skipped), compare baseline against the CURRENT
1236
+ // workspace state instead of the stale latest snapshot. This ensures the
1237
+ // preview shows meaningful changes even when the active turn has no snapshot.
1238
+ let latestManifest
1239
+ if (targetTurn > latest.turn && cwd) {
1240
+ const live = this.buildLiveManifest(cwd)
1241
+ latestManifest = live || latest.manifest
1242
+ } else {
1243
+ latestManifest = latest.manifest
1244
+ }
1206
1245
 
1207
1246
  // Calculate changes between latest and baseline: these are the files that
1208
1247
  // undo (restoring to baseline) will affect — every change made at or after
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-turn-undo",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Undo to any point in a DSH conversation — revert files and fork a new session",
5
5
  "type": "module",
6
6
  "main": "index.js",