{"_id":"@dianel/pi-workspace-history","_rev":"4-c2d2d07b89251bc567cc1de9a640ae8e","name":"@dianel/pi-workspace-history","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@dianel/pi-workspace-history","version":"1.0.0","keywords":["pi-package","workspace","undo","redo","pi-extension"],"_id":"@dianel/pi-workspace-history@1.0.0","maintainers":[{"name":"dianel","email":"desmonna@outlook.com"}],"pi":{"extensions":["./.pi/extensions/workspace-history.ts"]},"dist":{"shasum":"98ee8495140a391bfb045266e8a54638c6c7c826","tarball":"https://registry.npmjs.org/@dianel/pi-workspace-history/-/pi-workspace-history-1.0.0.tgz","fileCount":3,"integrity":"sha512-aUFCBUH2DRcSRjWjol/SxB3kpQDhgsGmLTbPlte1GAqFX++4bhAh/ne1H1P94hWtf+Pbn69l9pUkLYDLMLC9XA==","signatures":[{"sig":"MEQCIFUgarwh8Y2OTjtj4u50Vt3YTbRwTZ0Z7Ic7bJs+ly12AiBdNbz5FnACHcdIAqcprO4axRGtvNZN4iWl7gy/3yqXgw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":91622},"main":".pi/extensions/workspace-history.ts","type":"module","gitHead":"6aa11003966d5d9673f6f2b030fe3d7b3a949fb4","_npmUser":{"name":"dianel","email":"desmonna@outlook.com"},"_npmVersion":"11.19.0","description":"Real workspace undo/redo for Pi","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ignore":"^5.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":">=0.80.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-workspace-history_1.0.0_1788093491708_0.02147748950678019","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@dianel/pi-workspace-history","version":"1.0.1","keywords":["pi-package","pi-coding-agent","pi-extension","workspace","undo","redo"],"author":{"name":"Dianel555"},"license":"MIT","_id":"@dianel/pi-workspace-history@1.0.1","maintainers":[{"name":"dianel","email":"desmonna@outlook.com"}],"homepage":"https://github.com/Dianel555/Pi-tools/tree/main/packages/pi-workspace-history#readme","bugs":{"url":"https://github.com/Dianel555/Pi-tools/issues"},"pi":{"extensions":["./.pi/extensions/workspace-history.ts"]},"dist":{"shasum":"2b8868bcd12a3d3536811db439519be3886383ae","tarball":"https://registry.npmjs.org/@dianel/pi-workspace-history/-/pi-workspace-history-1.0.1.tgz","fileCount":5,"integrity":"sha512-Bj5KI/96tSv5wx1lzv9rD7E6KLMHIU4zCycD36kE7y8rYCzqagH0pXGg5xojOPcvAbv5q8ATR85/mB6Gfm8qGQ==","signatures":[{"sig":"MEQCIHXDGni+S70Pha78VZgZfN5Z2IcKOcvRH2ErQLQLvkHgAiByClnhhVxfslkQsd6y3VVmxy9CgAxk+Ha9ZJoNPUOqGg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":991642},"type":"module","engines":{"node":">=22.19.0"},"gitHead":"cc01a62c446962eaa49f28d50fcd8de479c0c02b","scripts":{"prepublishOnly":"npm --prefix ../.. run check"},"_npmUser":{"name":"dianel","email":"desmonna@outlook.com"},"repository":{"url":"git+https://github.com/Dianel555/Pi-tools.git","type":"git","directory":"packages/pi-workspace-history"},"_npmVersion":"11.19.0","description":"Real workspace undo/redo for Pi","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ignore":"^5.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-workspace-history_1.0.1_1788144332959_0.9160152115248783","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@dianel/pi-workspace-history","version":"1.0.2","keywords":["pi-package","pi-coding-agent","pi-extension","workspace","undo","redo"],"author":{"name":"Dianel555"},"license":"MIT","_id":"@dianel/pi-workspace-history@1.0.2","maintainers":[{"name":"dianel","email":"desmonna@outlook.com"}],"homepage":"https://github.com/Dianel555/Pi-tools/tree/main/packages/pi-workspace-history#readme","bugs":{"url":"https://github.com/Dianel555/Pi-tools/issues"},"pi":{"extensions":["./.pi/extensions/workspace-history.ts"]},"dist":{"shasum":"6f00d3f5db247798b02e2200bc3ed6ab601055ae","tarball":"https://registry.npmjs.org/@dianel/pi-workspace-history/-/pi-workspace-history-1.0.2.tgz","fileCount":5,"integrity":"sha512-+PitlItHI5NdIhhvZb0EB43b1cMtVH0GbX0/Lp/oH8PPKdc6JkQWtYy3KglHzaApwq00CRCoCgK79C3JYkTmfQ==","signatures":[{"sig":"MEUCIQCcWjEBDzDr9DJ1xhxZhddtl+gDTu5/2GLBc7W+ztkClgIgSzMw1HQqUeyv6sHY30Vuy13uOVsg2bdV/E3eR/Amz9U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1007665},"type":"module","engines":{"node":">=22.19.0"},"gitHead":"9d048e7064a168e19a79e9c94a3f7bc890cda831","scripts":{"prepublishOnly":"npm --prefix ../.. run check"},"_npmUser":{"name":"dianel","email":"desmonna@outlook.com"},"repository":{"url":"git+https://github.com/Dianel555/Pi-tools.git","type":"git","directory":"packages/pi-workspace-history"},"_npmVersion":"11.19.1","description":"Real workspace undo/redo for Pi","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ignore":"^5.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-workspace-history_1.0.2_1788263807267_0.12865405910398398","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"pi":{"extensions":["./.pi/extensions/workspace-history.ts"]},"_id":"@dianel/pi-workspace-history@1.0.3","bugs":{"url":"https://github.com/Dianel555/Pi-tools/issues"},"dist":{"shasum":"8e51cc90364665a5a1dae2ad9a8eb8e9afa63836","tarball":"https://registry.npmjs.org/@dianel/pi-workspace-history/-/pi-workspace-history-1.0.3.tgz","fileCount":5,"integrity":"sha512-caLU8ZMNJiOlLrHs+XVqsQhXlm1QuBDia7rBxPP7mQepd/6PxWoD6XHMBuPcsps+2pmLlnkTpq6AqJO9uxf9Aw==","signatures":[{"sig":"MEQCIE/dFWxvRaJvU1e/CbhbQLL/T2xXVabL+x0l+uTOm+2EAiAGhd47LX2F2wc01V36c9mdgW7L8tdzKyWSvoEcJSEicg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEbK6u6SshtrNt/6hqQgWywpwq9TCmS4g1UmteUBkxlDAiEAiEsMkHZ/CJid01lavANKatLi7PBQdKEClr7EOK/jpqk="}],"unpackedSize":1020529},"name":"@dianel/pi-workspace-history","type":"module","author":{"name":"Dianel555"},"engines":{"node":">=22.19.0"},"gitHead":"10092d4c3017e5bbb3cd73190077c3473d61fbec","license":"MIT","scripts":{"prepublishOnly":"npm --prefix ../.. run check"},"version":"1.0.3","_npmUser":{"name":"dianel","email":"desmonna@outlook.com"},"homepage":"https://github.com/Dianel555/Pi-tools/tree/main/packages/pi-workspace-history#readme","keywords":["pi-package","pi-coding-agent","pi-extension","workspace","undo","redo"],"repository":{"url":"git+https://github.com/Dianel555/Pi-tools.git","type":"git","directory":"packages/pi-workspace-history"},"_npmVersion":"11.19.1","description":"Real workspace undo/redo for Pi","directories":{},"maintainers":[{"name":"dianel","email":"desmonna@outlook.com"}],"_nodeVersion":"24.13.0","dependencies":{"ignore":"^5.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-workspace-history_1.0.3_1789906984423_0.1631474141163014"}}},"time":{"created":"2026-08-30T12:38:11.538Z","modified":"2026-09-20T12:23:04.710Z","1.0.0":"2026-08-30T12:38:11.866Z","1.0.1":"2026-08-31T02:45:33.148Z","1.0.2":"2026-09-01T11:56:47.435Z","1.0.3":"2026-09-20T12:23:04.553Z"},"bugs":{"url":"https://github.com/Dianel555/Pi-tools/issues"},"author":{"name":"Dianel555"},"license":"MIT","homepage":"https://github.com/Dianel555/Pi-tools/tree/main/packages/pi-workspace-history#readme","keywords":["pi-package","pi-coding-agent","pi-extension","workspace","undo","redo"],"repository":{"url":"git+https://github.com/Dianel555/Pi-tools.git","type":"git","directory":"packages/pi-workspace-history"},"description":"Real workspace undo/redo for Pi","maintainers":[{"name":"dianel","email":"desmonna@outlook.com"}],"readme":"# Pi Workspace History\n\nBased on [wcldyx/pi-workspace-history](https://github.com/wcldyx/pi-workspace-history).\n\nReal workspace undo/redo for Pi. Tracks file snapshots around each agent turn so you can time-travel your workspace state.\n\n## Install\n\n```bash\npi install npm:@dianel/pi-workspace-history\n```\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `/undo` | Restore workspace to before the last agent turn |\n| `/redo` | Re-apply the last undone turn |\n| `/checkpoint [label]` | Save a manual snapshot |\n| `/rewind [entry-id]` | Browse history interactively or jump to a specific entry |\n\n## How It Works\n\n- A lightweight shadow git repo stores file snapshots committed around each turn.\n- `before_agent_start` / `turn_start` snapshots the workspace before changes.\n- `turn_end` commits the state after.\n- `/undo` resets to the previous snapshot; `/redo` re-applies the undone turn.\n- `/checkpoint` creates a named manual snapshot for bookmarks.\n- `/rewind` opens a filterable history picker (↑↓ navigate, ⌃D/T/U/L/A cycle filters, ⌃X copy, ⇧L label, ⇧T time, ⌃←/→ branch).\n\n## Shortcuts (in `/rewind` picker)\n\n| Key | Action |\n|-----|--------|\n| ↑ / ↓ or j / k | Move selection |\n| ← / → | Page up / down |\n| Ctrl+← / Ctrl+→ | Branch |\n| Ctrl+X | Copy selected entry text |\n| Shift+L | Toggle label |\n| Shift+T | Toggle time |\n| Ctrl+D / T / U / L / A | Cycle filter mode |\n| Enter | Confirm selection |\n| Esc | Cancel |\n\n## Preview\n\nThe `/rewind` picker:\n\n![Rewind picker](assets/rewind.png)\n\n## Configuration\n\nConfigure the plugin through Pi settings. Project settings override global settings.\n\n- Global: `~/.pi/agent/settings.json`\n- Project: `.pi/settings.json`\n\nExample:\n\n```json\n{\n  \"workspaceHistory\": {\n    \"storageDir\": \"D:\\\\pi-history\",\n    \"maxSessionsPerWorkspace\": 3,\n    \"maxWorkspaces\": 10,\n    \"enabled\": \"auto\",\n    \"allowHomeDirectory\": false,\n    \"requireProjectMarker\": true,\n    \"maxScanFiles\": 20000,\n    \"maxScanDirs\": 3000,\n    \"maxScanMs\": 5000,\n    \"gitTimeoutMs\": 60000,\n    \"excludePatterns\": [\"*.tmp\", \"scratch/\", \"data/large/\"]\n  }\n}\n```\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| `workspaceHistory.storageDir` | `~/.pi/agent/state/workspace-history` | External storage root for shadow history |\n| `workspaceHistory.maxSessionsPerWorkspace` | `3` | Keep only the most recently used sessions per workspace |\n| `workspaceHistory.maxWorkspaces` | `10` | Keep only the most recently used workspaces globally |\n| `workspaceHistory.enabled` | `\"auto\"` | `\"auto\"` disables the plugin outside project-like directories; `true` forces it on; `false` disables it completely |\n| `workspaceHistory.allowHomeDirectory` | `false` | Allow the plugin to run in the user home directory |\n| `workspaceHistory.requireProjectMarker` | `true` | Require a project marker such as `.git` or `package.json` |\n| `workspaceHistory.maxScanFiles` | `20000` | Maximum number of files scanned when checking ignored/protected paths |\n| `workspaceHistory.maxScanDirs` | `3000` | Maximum number of directories scanned when checking ignored/protected paths |\n| `workspaceHistory.maxScanMs` | `5000` | Maximum time spent scanning ignored/protected paths, in milliseconds |\n| `workspaceHistory.gitTimeoutMs` | `60000` | Timeout for internal Git operations, in milliseconds |\n| `workspaceHistory.excludePatterns` | `[]` | Extra paths to exclude from snapshots, in `.gitignore` syntax. Appended to the built-in defaults; see below |\n\n## Excluded Paths\n\nThe 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.\n\nBuilt-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`.\n\nIf the project has a `.gitignore`, its rules are merged on top of the defaults. To exclude anything else, add `workspaceHistory.excludePatterns` (`.gitignore` syntax):\n\n```json\n{\n  \"workspaceHistory\": {\n    \"excludePatterns\": [\"*.tmp\", \"scratch/\", \"data/large/\"]\n  }\n}\n```\n\nPaths matched here are left untouched on disk during `/undo`, `/redo`, and `/rewind` — the plugin does not restore them, so use it only for files you are willing to keep as-is across a time-travel.\n\n## Debug Logging\n\nLogging is off by default. It is controlled by the `PI_WORKSPACE_HISTORY_LOG` **environment variable**. Accepted values are `1`, `true`, `yes`, and `on`.\n\n```powershell\n# PowerShell, before launching pi\n$env:PI_WORKSPACE_HISTORY_LOG = \"1\"\npi\n```\n\n```bash\n# bash / zsh\nPI_WORKSPACE_HISTORY_LOG=1 pi\n```\n\nThe 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.\n\nIt 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.\n\n## Installation and Usage\n\nInstall from npm after publishing:\n\n```bash\npi install npm:@dianel/pi-workspace-history\n```\n\nOr install from a local checkout:\n\n```bash\npi install /path/to/workspace-history\n```\n\nAfter installing into an already-running Pi session, run `/reload`. Then test with:\n\n```text\n/rewind\n/undo\n/redo\n/checkpoint test\n```\n\n## Local Development\n\nThe repository is configured for direct local extension loading:\n\n```text\n.pi/extensions/workspace-history.ts\n.pi/settings.json\n```\n\nStart Pi in the repository directory, or run `/reload` after changing the extension.\n\n## Testing\n\nRun the complete check suite:\n\n```bash\nnpm run check\n```\n\nOr run individual checks:\n\n```bash\nnpm test\nnpm run typecheck\nnpm pack --workspace @dianel/pi-workspace-history --dry-run\n```\n\n## Recent Changes\n\n- History is stored outside the workspace by default.\n- Added `workspaceHistory.storageDir`.\n- Added retention limits for sessions and workspaces.\n- Reduced runtime overhead with cached settings/paths and throttled cleanup.\n\n## Storage Layout\n\nThe plugin stores history outside the workspace by default:\n\n```text\n~/.pi/agent/state/workspace-history/\n  workspaces/\n    <workspaceHash>/\n      meta.json\n      sessions/\n        <sessionId>/\n          repo.git/\n          redo.json\n          turn-snapshots.json\n          meta.json\n  logs/\n    timemachine.log\n```\n\nNotes:\n\n- History is isolated from the user's project `.git` history.\n- Old workspace-local `.pi/workspace-history/` state is not migrated automatically.\n- Cleanup is LRU-style based on recent use.\n- In `auto` mode, the plugin disables itself in broad directories such as the user home folder to avoid expensive scans and startup stalls.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}