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 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 Hook
1
+ # Rewind Extension
2
2
 
3
- A Pi agent hook 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.
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.31+
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/hooks/rewind/`
25
- 2. Download the hook files
26
- 3. Add the hook to your `~/.pi/agent/settings.json`
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/hooks/rewind
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
- "hooks": ["~/.pi/agent/hooks/rewind/index.ts"]
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 hook creates git refs at two points:
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 hook 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).
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 hook directory:
179
+ 1. Remove the extension directory:
169
180
  ```bash
170
- rm -rf ~/.pi/agent/hooks/rewind
181
+ rm -rf ~/.pi/agent/extensions/rewind
171
182
  ```
172
- On Windows (PowerShell): `Remove-Item -Recurse -Force ~/.pi/agent/hooks/rewind`
183
+ On Windows (PowerShell): `Remove-Item -Recurse -Force ~/.pi/agent/extensions/rewind`
173
184
 
174
- 2. Remove the hook from `~/.pi/agent/settings.json` (delete the line with `rewind/index.ts` from the `hooks` array)
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 hook:
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 Hook - Git-based file restoration for pi branching
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.31+ (granular session events API)
7
+ * Updated for pi-coding-agent v0.35.0+ (unified extensions system)
8
8
  */
9
9
 
10
- import type { HookAPI } from "@mariozechner/pi-coding-agent";
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: HookAPI) {
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] Hook loaded`);
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 HOOK_DIR = path.join(os.homedir(), ".pi", "agent", "hooks", "rewind");
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 HOOK_PATH = "~/.pi/agent/hooks/rewind/index.ts";
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
- // Create hook directory
34
- console.log(`Creating directory: ${HOOK_DIR}`);
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 hookContent = await download(`${REPO_URL}/index.ts`);
40
- fs.writeFileSync(path.join(HOOK_DIR, "index.ts"), hookContent);
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(HOOK_DIR, "README.md"), readmeContent);
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
- // Ensure hooks array exists
60
- if (!Array.isArray(settings.hooks)) {
61
- settings.hooks = [];
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
- // Add hook if not already present
65
- if (!settings.hooks.includes(HOOK_PATH)) {
66
- settings.hooks.push(HOOK_PATH);
67
-
68
- // Ensure parent directory exists
69
- fs.mkdirSync(path.dirname(SETTINGS_FILE), { recursive: true });
70
- fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + "\n");
71
- console.log(`Added "${HOOK_PATH}" to hooks array`);
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("Hook already configured in settings.json");
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 hook will load automatically when you start pi.");
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.2.0",
4
- "description": "Rewind hook for Pi agent - automatic git checkpoints with file/conversation restore",
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
- "hook",
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
  }