pi-rewind-hook 1.2.0 → 1.3.0
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.
- package/CHANGELOG.md +12 -0
- package/README.md +26 -15
- package/index.ts +5 -5
- package/install.js +51 -24
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.3.0] - 2026-01-05
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
- Requires pi v0.35.0+ (unified extensions system)
|
|
9
|
+
- Install location changed from `hooks/rewind` to `extensions/rewind`
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Migrated from hooks to unified extensions system
|
|
13
|
+
- Settings key changed from `hooks` to `extensions`
|
|
14
|
+
- Install script now migrates old hooks config and cleans up old directory
|
|
15
|
+
- Renamed "Hook" to "Extension" throughout codebase and docs
|
|
16
|
+
|
|
5
17
|
## [1.2.0] - 2025-01-03
|
|
6
18
|
|
|
7
19
|
### Added
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Rewind
|
|
1
|
+
# Rewind Extension
|
|
2
2
|
|
|
3
|
-
A Pi agent
|
|
3
|
+
A Pi agent extension that enables rewinding file changes during coding sessions. Creates automatic checkpoints using git refs, allowing you to restore files to previous states while optionally preserving conversation history.
|
|
4
4
|
|
|
5
5
|
## Screenshots
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ A Pi agent hook that enables rewinding file changes during coding sessions. Crea
|
|
|
10
10
|
|
|
11
11
|
## Requirements
|
|
12
12
|
|
|
13
|
-
- Pi agent v0.
|
|
13
|
+
- Pi agent v0.35.0+ (unified extensions system)
|
|
14
14
|
- Node.js (for installation)
|
|
15
15
|
- Git repository (checkpoints are stored as git refs)
|
|
16
16
|
|
|
@@ -21,9 +21,11 @@ npx pi-rewind-hook
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
This will:
|
|
24
|
-
1. Create `~/.pi/agent/
|
|
25
|
-
2. Download the
|
|
26
|
-
3. Add the
|
|
24
|
+
1. Create `~/.pi/agent/extensions/rewind/`
|
|
25
|
+
2. Download the extension files
|
|
26
|
+
3. Add the extension to your `~/.pi/agent/settings.json`
|
|
27
|
+
4. Migrate any existing hooks config to extensions (if upgrading from v1.2.0)
|
|
28
|
+
5. Clean up old `hooks/rewind` directory (if present)
|
|
27
29
|
|
|
28
30
|
### Alternative Installation
|
|
29
31
|
|
|
@@ -36,14 +38,14 @@ curl -fsSL https://raw.githubusercontent.com/nicobailon/pi-rewind-hook/main/inst
|
|
|
36
38
|
Or clone the repo and configure manually:
|
|
37
39
|
|
|
38
40
|
```bash
|
|
39
|
-
git clone https://github.com/nicobailon/pi-rewind-hook ~/.pi/agent/
|
|
41
|
+
git clone https://github.com/nicobailon/pi-rewind-hook ~/.pi/agent/extensions/rewind
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
Then add to `~/.pi/agent/settings.json`:
|
|
43
45
|
|
|
44
46
|
```json
|
|
45
47
|
{
|
|
46
|
-
"
|
|
48
|
+
"extensions": ["~/.pi/agent/extensions/rewind/index.ts"]
|
|
47
49
|
}
|
|
48
50
|
```
|
|
49
51
|
|
|
@@ -55,11 +57,20 @@ Then add to `~/.pi/agent/settings.json`:
|
|
|
55
57
|
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/nicobailon/pi-rewind-hook/main/install.js" -OutFile install.js; node install.js; Remove-Item install.js
|
|
56
58
|
```
|
|
57
59
|
|
|
60
|
+
### Upgrading from v1.2.0
|
|
61
|
+
|
|
62
|
+
If you're upgrading from pi-rewind-hook v1.2.0 (which used the hooks system), simply run `npx pi-rewind-hook` again. The installer will:
|
|
63
|
+
- Move the extension from `hooks/rewind` to `extensions/rewind`
|
|
64
|
+
- Migrate your settings.json from `hooks` to `extensions`
|
|
65
|
+
- Clean up the old hooks directory
|
|
66
|
+
|
|
67
|
+
**Note:** v1.3.0+ requires pi v0.35.0 or later. If you're on an older version of pi, stay on pi-rewind-hook v1.2.0.
|
|
68
|
+
|
|
58
69
|
## How It Works
|
|
59
70
|
|
|
60
71
|
### Checkpoints
|
|
61
72
|
|
|
62
|
-
The
|
|
73
|
+
The extension creates git refs at two points:
|
|
63
74
|
|
|
64
75
|
1. **Session start** - When pi starts, creates a "resume checkpoint" of the current file state
|
|
65
76
|
2. **Each turn** - Before the agent processes each message, creates a checkpoint
|
|
@@ -100,7 +111,7 @@ To rewind via tree navigation:
|
|
|
100
111
|
|
|
101
112
|
### Resumed Sessions
|
|
102
113
|
|
|
103
|
-
When you resume a session (`pi --resume`), the
|
|
114
|
+
When you resume a session (`pi --resume`), the extension creates a resume checkpoint. If you branch to a message from before the current session, you can restore files to the state when you resumed (not per-message granularity, but a safety net).
|
|
104
115
|
|
|
105
116
|
## Examples
|
|
106
117
|
|
|
@@ -165,15 +176,15 @@ git for-each-ref --format='%(refname)' refs/pi-checkpoints/ | xargs -n1 git upda
|
|
|
165
176
|
|
|
166
177
|
## Uninstalling
|
|
167
178
|
|
|
168
|
-
1. Remove the
|
|
179
|
+
1. Remove the extension directory:
|
|
169
180
|
```bash
|
|
170
|
-
rm -rf ~/.pi/agent/
|
|
181
|
+
rm -rf ~/.pi/agent/extensions/rewind
|
|
171
182
|
```
|
|
172
|
-
On Windows (PowerShell): `Remove-Item -Recurse -Force ~/.pi/agent/
|
|
183
|
+
On Windows (PowerShell): `Remove-Item -Recurse -Force ~/.pi/agent/extensions/rewind`
|
|
173
184
|
|
|
174
|
-
2. Remove the
|
|
185
|
+
2. Remove the extension from `~/.pi/agent/settings.json` (delete the line with `rewind/index.ts` from the `extensions` array)
|
|
175
186
|
|
|
176
|
-
3. Optionally, clean up git refs in each repo where you used the
|
|
187
|
+
3. Optionally, clean up git refs in each repo where you used the extension:
|
|
177
188
|
```bash
|
|
178
189
|
git for-each-ref --format='%(refname)' refs/pi-checkpoints/ | xargs -n1 git update-ref -d
|
|
179
190
|
```
|
package/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Rewind
|
|
2
|
+
* Rewind Extension - Git-based file restoration for pi branching
|
|
3
3
|
*
|
|
4
4
|
* Creates worktree snapshots at each turn so /branch can restore code state.
|
|
5
5
|
* Supports: restore files + conversation, files only, conversation only, undo last restore.
|
|
6
6
|
*
|
|
7
|
-
* Updated for pi-coding-agent v0.
|
|
7
|
+
* Updated for pi-coding-agent v0.35.0+ (unified extensions system)
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
11
11
|
import { exec as execCb } from "child_process";
|
|
12
12
|
import { mkdtemp, rm } from "fs/promises";
|
|
13
13
|
import { tmpdir } from "os";
|
|
@@ -22,14 +22,14 @@ const MAX_CHECKPOINTS = 100;
|
|
|
22
22
|
|
|
23
23
|
type ExecFn = (cmd: string, args: string[]) => Promise<{ stdout: string; stderr: string; code: number }>;
|
|
24
24
|
|
|
25
|
-
export default function (pi:
|
|
25
|
+
export default function (pi: ExtensionAPI) {
|
|
26
26
|
const checkpoints = new Map<string, string>();
|
|
27
27
|
let currentEntryId: string | undefined;
|
|
28
28
|
let resumeCheckpoint: string | null = null;
|
|
29
29
|
let repoRoot: string | null = null;
|
|
30
30
|
let isGitRepo = false;
|
|
31
31
|
|
|
32
|
-
console.error(`[rewind]
|
|
32
|
+
console.error(`[rewind] Extension loaded`);
|
|
33
33
|
|
|
34
34
|
async function findBeforeRestoreRef(exec: ExecFn): Promise<{ refName: string; commitSha: string } | null> {
|
|
35
35
|
try {
|
package/install.js
CHANGED
|
@@ -6,9 +6,10 @@ const https = require("https");
|
|
|
6
6
|
const os = require("os");
|
|
7
7
|
|
|
8
8
|
const REPO_URL = "https://raw.githubusercontent.com/nicobailon/pi-rewind-hook/main";
|
|
9
|
-
const
|
|
9
|
+
const EXT_DIR = path.join(os.homedir(), ".pi", "agent", "extensions", "rewind");
|
|
10
|
+
const OLD_HOOK_DIR = path.join(os.homedir(), ".pi", "agent", "hooks", "rewind");
|
|
10
11
|
const SETTINGS_FILE = path.join(os.homedir(), ".pi", "agent", "settings.json");
|
|
11
|
-
const
|
|
12
|
+
const EXT_PATH = "~/.pi/agent/extensions/rewind/index.ts";
|
|
12
13
|
|
|
13
14
|
function download(url) {
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
@@ -28,22 +29,19 @@ function download(url) {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
async function main() {
|
|
31
|
-
console.log("Installing pi-rewind-hook...\n");
|
|
32
|
+
console.log("Installing pi-rewind-hook (Rewind Extension)...\n");
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
console.log(`
|
|
35
|
-
fs.mkdirSync(HOOK_DIR, { recursive: true });
|
|
34
|
+
fs.mkdirSync(EXT_DIR, { recursive: true });
|
|
35
|
+
console.log(`Created directory: ${EXT_DIR}`);
|
|
36
36
|
|
|
37
|
-
// Download hook files
|
|
38
37
|
console.log("Downloading index.ts...");
|
|
39
|
-
const
|
|
40
|
-
fs.writeFileSync(path.join(
|
|
38
|
+
const extContent = await download(`${REPO_URL}/index.ts`);
|
|
39
|
+
fs.writeFileSync(path.join(EXT_DIR, "index.ts"), extContent);
|
|
41
40
|
|
|
42
41
|
console.log("Downloading README.md...");
|
|
43
42
|
const readmeContent = await download(`${REPO_URL}/README.md`);
|
|
44
|
-
fs.writeFileSync(path.join(
|
|
43
|
+
fs.writeFileSync(path.join(EXT_DIR, "README.md"), readmeContent);
|
|
45
44
|
|
|
46
|
-
// Update settings.json
|
|
47
45
|
console.log(`\nUpdating settings: ${SETTINGS_FILE}`);
|
|
48
46
|
|
|
49
47
|
let settings = {};
|
|
@@ -56,25 +54,54 @@ async function main() {
|
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
settings.
|
|
57
|
+
if (settings.hooks && Array.isArray(settings.hooks) && settings.hooks.length > 0) {
|
|
58
|
+
console.log("\nMigrating hooks to extensions...");
|
|
59
|
+
if (!Array.isArray(settings.extensions)) {
|
|
60
|
+
settings.extensions = [];
|
|
61
|
+
}
|
|
62
|
+
for (const entry of settings.hooks) {
|
|
63
|
+
if (entry.includes("/hooks/rewind")) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const newPath = entry.replace("/hooks/", "/extensions/");
|
|
67
|
+
if (!settings.extensions.includes(newPath)) {
|
|
68
|
+
settings.extensions.push(newPath);
|
|
69
|
+
console.log(` Migrated: ${entry} -> ${newPath}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
delete settings.hooks;
|
|
73
|
+
console.log("Removed old 'hooks' key from settings");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!Array.isArray(settings.extensions)) {
|
|
77
|
+
settings.extensions = [];
|
|
62
78
|
}
|
|
63
79
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
const EXT_PATH_ALT = "~/.pi/agent/extensions/rewind";
|
|
81
|
+
const hasRewindExt = settings.extensions.some(p =>
|
|
82
|
+
p === EXT_PATH || p === EXT_PATH_ALT ||
|
|
83
|
+
p.includes("/extensions/rewind/index.ts") ||
|
|
84
|
+
p.endsWith("/extensions/rewind")
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (!hasRewindExt) {
|
|
88
|
+
settings.extensions.push(EXT_PATH);
|
|
89
|
+
console.log(`Added "${EXT_PATH}" to extensions array`);
|
|
72
90
|
} else {
|
|
73
|
-
console.log("
|
|
91
|
+
console.log("Extension already configured in settings.json");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
fs.mkdirSync(path.dirname(SETTINGS_FILE), { recursive: true });
|
|
95
|
+
fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + "\n");
|
|
96
|
+
|
|
97
|
+
if (fs.existsSync(OLD_HOOK_DIR)) {
|
|
98
|
+
console.log(`\nCleaning up old hooks directory: ${OLD_HOOK_DIR}`);
|
|
99
|
+
fs.rmSync(OLD_HOOK_DIR, { recursive: true, force: true });
|
|
100
|
+
console.log("Removed old hooks/rewind directory");
|
|
74
101
|
}
|
|
75
102
|
|
|
76
103
|
console.log("\nInstallation complete!");
|
|
77
|
-
console.log("\nThe rewind
|
|
104
|
+
console.log("\nThe rewind extension will load automatically when you start pi.");
|
|
78
105
|
console.log("Use /branch to rewind to a previous checkpoint.");
|
|
79
106
|
}
|
|
80
107
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-rewind-hook",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Rewind
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Rewind extension for Pi agent - automatic git checkpoints with file/conversation restore",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pi-rewind-hook": "./install.js"
|
|
7
7
|
},
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
"keywords": [
|
|
13
13
|
"pi",
|
|
14
14
|
"pi-agent",
|
|
15
|
-
"
|
|
15
|
+
"extension",
|
|
16
16
|
"checkpoint",
|
|
17
17
|
"rewind",
|
|
18
18
|
"git"
|
|
19
19
|
],
|
|
20
20
|
"author": "nicobailon",
|
|
21
|
-
"license": "MIT"
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"pi": {
|
|
23
|
+
"extensions": ["./index.ts"]
|
|
24
|
+
}
|
|
22
25
|
}
|