@tduyng/pi-rewind
v0.0.5
Published
Go back in a session and the files go back too: a git snapshot before every prompt, restored on /tree, /fork and /rewind.
Maintainers
Readme
@tduyng/pi-rewind
/tree and /fork take the conversation back to an earlier prompt, and the files stay where the agent left them. The model then reasons about code that no longer matches what it sees, and undoing the agent's edits by hand is the work a rewind was meant to save.
This package takes the files back too. It adds nothing to a request: no tool, no prompt text.
How it works
Before each prompt runs, the work tree is written to a git commit under refs/pi-rewind/<session>/before/<prompt entry>. When a run settles, the end state goes under after/<last entry>. Tracked edits, deletions, and untracked files that are not ignored are all included. The snapshot goes through a temporary index, so your staging area, stash, branches, and git status never change.
Every snapshot is a fresh commit, even when the tree matches the last one. Git stores an identical tree once, so the extra cost is a commit object of about 200 bytes. The prune at session start drops refs whose commit is older than 14 days, and reusing an old commit for a new prompt once made that prune delete yesterday's checkpoint.
/treeto an earlier prompt, or/forkfrom one, asks whether to rewind the files as well and lists what would change./rewindpicks a prompt on the current branch and rewinds only the files. The conversation stays, and the model is told on its next turn which paths changed under it./rewind 2takes the second newest checkpoint without a picker, and a client with no UI takes the newest./rewind undoreverses the last rewind. Every rewind first saves the current tree, so a rewind is never the last copy of anything.
A restore writes the files that differ and deletes the files the target never had. Files that are the same are left alone, so their timestamps do not change and a watcher does not rebuild them.
A file changed since the agent last finished is left alone too, and the confirm prompt lists it. That covers an edit you made in your editor, a ! command, or another pi session in the same repository. The agent's own edits are the ones a rewind takes back.
Cost
Nothing in the context. The snapshot starts when the prompt is sent, and the first tool call waits for whatever is left of it, so no edit can land before the snapshot. Measured on this machine: about 95 ms on a repository of 419 tracked files and about 360 ms on one of 31,572. That is shorter than the model's first response, so the prompt does not wait.
Unchanged files share git objects with your history, so a snapshot stores only what differs. Refs older than 14 days are deleted at session start, and git gc reclaims their objects as it would any unreachable commit.
Install
pi install npm:@tduyng/pi-rewindLocal checkout: pi install /path/to/dotfiles/pi/agent/extensions/pi-rewind
Needs git 2.26 or newer. Outside a git work tree the package does nothing.
Limits
- An untracked file over 5 MiB is left out of every snapshot, so a rewind neither restores nor deletes it. Data files that are not ignored stay where they are.
- Ignored files are never touched.
- The staging area is not restored. A rewind changes the work tree only.
- A
/treetarget in the middle of a run has no snapshot of its own, so only prompts and the ends of runs can be rewound to. - Two sessions running at the same time in one repository are not told apart. A file another session changes while this one runs counts as this session's edit.
- A forked session starts its own snapshots. Its copied prompts rewind from the parent session only through
/forkitself.
