omp packages

@dianel/pi-workspace-history1.0.4

Real workspace undo/redo for Pi

dianel Published 2 days ago MIT ~279 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

Pi Workspace History

Based on wcldyx/pi-workspace-history.

Real workspace undo/redo for Pi. Tracks file snapshots around each agent turn so you can time-travel your workspace state.

Install

pi install npm:@dianel/pi-workspace-history

Commands

Command Description
/undo Restore workspace to before the last agent turn
/redo Re-apply the last undone turn
/checkpoint [label] Save a manual snapshot
/rewind [entry-id] Browse history interactively or jump to a specific entry

How It Works

  • A lightweight shadow git repo stores file snapshots committed around each turn.
  • before_agent_start / turn_start snapshots the workspace before changes.
  • turn_end commits the state after.
  • /undo resets to the previous snapshot; /redo re-applies the undone turn.
  • /checkpoint creates a named manual snapshot for bookmarks.
  • /rewind opens a filterable history picker (↑↓ navigate, ⌃D/T/U/L/A cycle filters, ⌃X copy, ⇧L label, ⇧T time, ⌃←/→ branch).

Shortcuts (in /rewind picker)

Key Action
↑ / ↓ or j / k Move selection
← / → Page up / down
Ctrl+← / Ctrl+→ Branch
Ctrl+X Copy selected entry text
Shift+L Toggle label
Shift+T Toggle time
Ctrl+D / T / U / L / A Cycle filter mode
Enter Confirm selection
Esc Cancel

Preview

The /rewind picker:

Rewind picker

Configuration

Configure the plugin through Pi settings. Trusted project settings override global settings; untrusted projects use only global settings.

  • Global: ~/.pi/agent/settings.json
  • Project: .pi/settings.json

Example:

{
  "workspaceHistory": {
    "storageDir": "D:\\pi-history",
    "maxSessionsPerWorkspace": 3,
    "maxWorkspaces": 10,
    "enabled": "auto",
    "allowHomeDirectory": false,
    "requireProjectMarker": true,
    "maxScanFiles": 20000,
    "maxScanDirs": 3000,
    "maxScanMs": 5000,
    "gitTimeoutMs": 60000,
    "excludePatterns": ["*.tmp", "scratch/", "data/large/"]
  }
}
Setting Default Description
workspaceHistory.storageDir ~/.pi/agent/state/workspace-history External storage root; it and the workspace must not contain each other, including through symlinks
workspaceHistory.maxSessionsPerWorkspace 3 Keep only the most recently used sessions per workspace
workspaceHistory.maxWorkspaces 10 Keep only the most recently used workspaces globally
workspaceHistory.enabled "auto" "auto" disables the plugin outside project-like directories; true bypasses directory checks but not storage-overlap validation; false disables it completely
workspaceHistory.allowHomeDirectory false Allow the plugin to run in the user home directory
workspaceHistory.requireProjectMarker true Require a marker in the current directory, such as .git, package.json, pyproject.toml, Cargo.toml, or go.mod
workspaceHistory.maxScanFiles 20000 Maximum number of files scanned when checking ignored/protected paths
workspaceHistory.maxScanDirs 3000 Maximum number of directories scanned when checking ignored/protected paths
workspaceHistory.maxScanMs 5000 Maximum time spent scanning ignored/protected paths, in milliseconds
workspaceHistory.gitTimeoutMs 60000 Pi process timeout for internal Git operations, in milliseconds
workspaceHistory.excludePatterns [] Extra paths to exclude from snapshots, in .gitignore syntax. Appended to the built-in defaults; see below

Excluded Paths

The plugin never snapshots large, regenerable, non-source paths, so that time-travel stays fast and history stays small. This works even in a project with no .gitignore and no Git repository at all — the defaults are built in, not read from the project.

Built-in defaults: .git, .pi/workspace-history, node_modules, dist, build, .cache, .next, .turbo, coverage, .env, .env.*, tmp, temp, logs, *.log, __pycache__, *.pyc, .venv, venv, .pytest_cache, .mypy_cache, .ruff_cache, .gradle, .idea, .DS_Store.

If the project has a .gitignore, its rules are merged on top of the defaults. To exclude anything else, add workspaceHistory.excludePatterns (.gitignore syntax):

{
  "workspaceHistory": {
    "excludePatterns": ["*.tmp", "scratch/", "data/large/"]
  }
}

Paths matched by the current rules are left unchanged during /undo, /redo, and /rewind, including when they are currently absent but present in an older snapshot. A restore stops before changing files if a required backup fails. If excluded-path recovery fails, the error reports the retained excluded-backup-* directory for manual recovery.

Git index locks are never automatically removed based on age. After a crashed Git operation, check that no process owns the lock before removing it manually.

Debug Logging

Logging is off by default. It is controlled by the PI_WORKSPACE_HISTORY_LOG environment variable. Accepted values are 1, true, yes, and on.

# PowerShell, before launching pi
$env:PI_WORKSPACE_HISTORY_LOG = "1"
pi
# bash / zsh
PI_WORKSPACE_HISTORY_LOG=1 pi

The log is written to <storageDir>/logs/timemachine.log — by default ~/.pi/agent/state/workspace-history/logs/timemachine.log, or under workspaceHistory.storageDir when that is set.

It records snapshot commits, Git invocations with timings, restore and navigation outcomes, and how many paths each restore had to back up. That makes it the first thing to enable when a /rewind, /undo, or /redo behaves unexpectedly.

Installation and Usage

Install from npm after publishing:

pi install npm:@dianel/pi-workspace-history

Or install from a local checkout:

pi install /path/to/workspace-history

After installing into an already-running Pi session, run /reload. Then test with:

/rewind
/undo
/redo
/checkpoint test

Local Development

The repository is configured for direct local extension loading:

.pi/extensions/workspace-history.ts
.pi/settings.json

Start Pi in the repository directory, or run /reload after changing the extension.

Testing

Run the complete check suite:

npm run check

Or run individual checks:

npm test
npm run typecheck
npm pack --workspace @dianel/pi-workspace-history --dry-run

Recent Changes

  • 1.0.4: tested against Pi 1.3.0; custom-message runs no longer attach snapshots to a previous user turn.
  • Queued steering snapshots follow the delivered user message, not the preceding custom or user response; tool-result leaves use Pi's persisted assistant anchor.
  • Restored actual file undo/redo with cancellation rollback and dirty-workspace protection.
  • Hardened project trust, storage validation, Git timeouts/locks, and excluded-path recovery.
  • History is stored outside the workspace by default.
  • Added workspaceHistory.storageDir.
  • Added retention limits for sessions and workspaces.
  • Reduced runtime overhead with cached settings/paths and throttled cleanup.

Storage Layout

The plugin stores history outside the workspace by default:

~/.pi/agent/state/workspace-history/
  workspaces/
    <workspaceHash>/
      meta.json
      sessions/
        <sessionId>/
          repo.git/
          redo.json
          turn-snapshots.json
          meta.json
  logs/
    timemachine.log

Notes:

  • History is isolated from the user's project .git history.
  • Old workspace-local .pi/workspace-history/ state is not migrated automatically.
  • Cleanup is LRU-style based on recent use.
  • In auto mode, the plugin disables itself in broad directories such as the user home folder to avoid expensive scans and startup stalls.

License

MIT