co-mono/packages/coding-agent/examples/hooks/git-checkpoint.ts
Mario Zechner e7097d911a Custom tools with session lifecycle, examples for hooks and tools
- Custom tools: TypeScript modules that extend pi with new tools
  - Custom TUI rendering via renderCall/renderResult
  - User interaction via pi.ui (select, confirm, input, notify)
  - Session lifecycle via onSession callback for state reconstruction
  - Examples: todo.ts, question.ts, hello.ts

- Hook examples: permission-gate, git-checkpoint, protected-paths

- Session lifecycle centralized in AgentSession
  - Works across all modes (interactive, print, RPC)
  - Unified session event for hooks (replaces session_start/session_switch)

- Box component added to pi-tui

- Examples bundled in npm and binary releases

Fixes #190
2025-12-17 16:03:23 +01:00

48 lines
1.2 KiB
TypeScript

/**
* Git Checkpoint Hook
*
* Creates git stash checkpoints at each turn so /branch can restore code state.
* When branching, offers to restore code to that point in history.
*/
import type { HookAPI } from "@mariozechner/pi-coding-agent/hooks";
export default function (pi: HookAPI) {
const checkpoints = new Map<number, string>();
pi.on("turn_start", async (event, ctx) => {
// Create a git stash entry before LLM makes changes
const { stdout } = await ctx.exec("git", ["stash", "create"]);
const ref = stdout.trim();
if (ref) {
checkpoints.set(event.turnIndex, ref);
}
});
pi.on("branch", async (event, ctx) => {
const ref = checkpoints.get(event.targetTurnIndex);
if (!ref) return undefined;
if (!ctx.hasUI) {
// In non-interactive mode, don't restore automatically
return undefined;
}
const choice = await ctx.ui.select("Restore code state?", [
"Yes, restore code to that point",
"No, keep current code",
]);
if (choice?.startsWith("Yes")) {
await ctx.exec("git", ["stash", "apply", ref]);
ctx.ui.notify("Code restored to checkpoint", "info");
}
return undefined;
});
pi.on("agent_end", async () => {
// Clear checkpoints after agent completes
checkpoints.clear();
});
}