@baylarsadigov/omp-undo-redo

Undo and redo session navigation for Pi and Oh My Pi

Packages

Package details

extension

Install @baylarsadigov/omp-undo-redo from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@baylarsadigov/omp-undo-redo
Package
@baylarsadigov/omp-undo-redo
Version
1.8.0
Published
Oct 22, 2026
Downloads
1,741/mo · 441/wk
Author
baylarsadigov
License
MIT
Types
extension
Size
559.2 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./dist/index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

OMP Undo/Redo

npm version CI

/undo and /redo for Oh My Pi (OMP) and Pi. /undo takes the conversation back to your last prompt and puts your files back as they were before that turn; /redo goes forward again. No changes to the agent's source or session format.

Know this before relying on it:

  • Snapshots are plaintext copies of your worktree, kept outside the repository: in Git projects, unignored files such as .env.local; in non-Git folders, .env and private keys too. They are deleted 2 days (configurable) after the session's last use, not securely erased. Git LFS file content is kept longer; see SECURITY.md.
  • /undo reverts every file changed during the turn, including edits from your editor or a build watcher, and lists what it restored.
  • Not restored: ignored files, nested Git repositories, files locked by another program, Git LFS content removed by git lfs prune. A turn that touched files under a symlink or Windows junction cannot be undone or redone until the link is replaced.
  • No file snapshots in a non-Git home directory, drive root or temp directory: only the conversation moves back.

Details: What gets stored and what isn't restored. Problems: Troubleshooting.

Installation

Requires OMP 18.3.2+ (extensions run under Bun) or Pi with Node.js 20+, and Git. Without Git, or if the snapshot store cannot be set up, undo/redo moves only the conversation and you are told once per session. Store setup is retried every turn; a missing Git is not.

Install through the agent; a plain npm install does not register the extension.

# OMP
omp plugin install @baylarsadigov/omp-undo-redo
omp plugin install @baylarsadigov/omp-undo-redo@1.8.0   # pin a release

# Pi
pi install npm:@baylarsadigov/omp-undo-redo
pi install npm:@baylarsadigov/omp-undo-redo@1.8.0       # pin a release
pi update --extensions                                  # update

In Pi, confirm with pi list and restart the TUI; /undo and /redo then appear in slash-command completion.

Usage

  • /undo goes back to the latest prompt, dropping the assistant's reply and tool activity and restoring the files changed in that turn. The prompt itself stays in the session tree.
  • /redo reapplies the last undo. A new prompt or any other successful tree or session navigation clears redo history; /undo, /redo, and cancelled or no-op navigation keep it.

Neither command takes arguments or starts a model turn. Both wait for the agent to become idle (no time limit), then up to 3 s each for an in-flight snapshot and for the last turn's finalize; if either is still running, nothing changes and you get a warning.

Snapshots are taken when a turn starts and when it ends, so anything that changes a file mid-turn (a formatter on save, another OMP process in the same repository) is reverted with the agent's edits. Check the restored-file list ("Restored files: notes.md, src/app.ts.") for files the agent did not touch. Edits made after the turn are safe: if they overlap the turn's changes, /undo refuses and names the conflicting files; otherwise they stay in place.

  • Restarts: history survives resuming the session in the same worktree until retention expires. If file history is missing, undo moves only the conversation, with a warning.
  • Subagents (task, eval agent(), /tan) have no undo of their own; their edits belong to the parent turn.
  • Staged changes stay staged: the Git index is never touched, so git status may show MM. See Staged changes after undo or redo.
  • Interrupted undo/redo is settled on the next session load. If files were left partly restored, follow Restoring files after an interrupted undo or redo.
  • Limits: about 9,000 turns of history survive a resume. A turn whose first snapshot is not ready within 25 s of a tool call is recorded conversation-only.

Internals: docs/architecture.md.

What gets stored and what isn't restored

Snapshots are plaintext Git objects in the store (~/.omp/omp-undo-redo/repos/ by default), kept for the retention period:

  • Git projects: tracked files plus untracked files .gitignore does not exclude. Your HEAD, branches and index are never touched, and mirror push/clone, git bundle create --all and git log --all never see the snapshots.
  • Non-Git folders: everything except the built-in ignore list (.git, .hg, .svn, node_modules, .history, dist, coverage, .omp, .next, build, out, target, .vs, .idea, __pycache__, .venv, .gradle), matched at any depth. So .env, id_rsa, *.pem are included, and a hand-written docs/build/ is not.
  • Through a Windows junction (mklink /J): Git reads it as a plain folder, so snapshots also copy the files it points at, even outside the workspace. Directory symlinks are stored as links and never followed.
  • Skipped entirely: your own home directory without Git (and folders above it such as C:\Users or /home), drive roots, your OS temp directory and the shared temp directories (/tmp, /var/tmp, C:\Windows\Temp), since snapshotting would copy .ssh, AppData, browser profiles or other users' temp files. Their subfolders are normal workspaces. Running git init there does not make it safe: Git mode then snapshots everything not gitignored.

Left as they are by /undo and /redo:

  • Ignored files: matched by .gitignore or the built-in list.
  • Nested Git repositories and submodules: contents and HEAD untouched; the result names them.
  • Files Git could not read at snapshot time (locked, e.g. Visual Studio's .vs databases, or no read permission); the result names them.
  • Pruned Git LFS files: snapshotting runs clean filters like git add, writing LFS objects to .git/lfs/objects (or the store's lfs/ for non-Git folders). If git lfs prune removed one and LFS cannot download it again, the restore is rolled back; if the file's current version was pruned too, it is left empty.
  • Rewritten history: in Git mode, content reachable from HEAD is shared with your repository until the next store gc. Rewriting and pruning it before then (git filter-repo, BFG) makes those checkpoints unrestorable; undo/redo reports the failure rather than restoring part of them. Normal git gc --prune=now is safe.

Refused whole: an undo or redo that would write, create or delete a file under a symlink or junction in the workspace writes nothing and names those files. See Undo or redo refused: files under a symlink or junction.

Configuration

Optional environment variables, read once at startup and applied process-wide (e.g. export OMP_UNDO_REDO_RETENTION_DAYS=7, or setx OMP_UNDO_REDO_RETENTION_DAYS 7 on Windows, then open a new terminal).

Variable Default Meaning
OMP_UNDO_REDO_RETENTION_DAYS 2 Days file history is kept after a session's last use. Fractions allowed; 0 keeps it forever; invalid values are ignored.
OMP_UNDO_REDO_STORE_DIR ~/.omp/omp-undo-redo Store and history root (legacy alias OMP_UNDO_REDO_BLOB_DIR). Changing it starts an empty store: older turns can no longer restore files, and the old directory is not moved or deleted.
OMP_UNDO_REDO_RUNTIME_DIR ~/.omp/omp-undo-redo/runtime Action state for external clients. Without a store variable, the store follows it: to its parent if the directory is named runtime, otherwise to itself.
OMP_UNDO_REDO_DEBUG unset 1 logs every git command, including your paths, to <storeRoot>/debug.log. See Collecting a debug trace.

Store directories are created owner-only (0700 on Linux/macOS; on Windows they inherit the parent's ACL); a root you set yourself keeps its permissions.

Expiry runs in the background shortly after startup, covers every store, and never touches a session in use. Expired turns resume conversation-only, with a warning. Stores of deleted workspaces are set aside after 24 idle hours and removed 7 days later. Details: Storage maintenance.

Contributing

npm run verify runs format, lint, typecheck, tests, build and package checks. Use only public OMP extension APIs and do not commit dist/. See CONTRIBUTING.md; releases follow RELEASE.md (never commit npm tokens or secrets). Report vulnerabilities per SECURITY.md, not in public issues; bugs and feature requests go to the issue tracker.

License

MIT. Copyright © 2026 Baylar Sadigov.