Skip to content

Instantly share code, notes, and snippets.

@badlogic
Created January 16, 2026 13:53
Show Gist options
  • Select an option

  • Save badlogic/64bf5ff34a7164446dc2ad25c8a3eb19 to your computer and use it in GitHub Desktop.

Select an option

Save badlogic/64bf5ff34a7164446dc2ad25c8a3eb19 to your computer and use it in GitHub Desktop.
Pi extension: /review command - branch from root, work, return with summary (in-session branching)
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
/**
* /review command - Create a review branch from root, return with summary
*
* Usage:
* /review - Start review branch from root
* /end-review - Return to origin with auto-summary
* /end-review <text> - Return with custom summary text
*
* How it works:
* - Stores your current position
* - Navigates to root (creates new branch in same session)
* - User works in review branch
* - Returns to origin with summary of review work
*/
export default function (pi: ExtensionAPI) {
// Store where we branched from
let reviewOriginId: string | undefined;
pi.registerCommand("review", {
description: "Start a review branch from root, return when done",
handler: async (args, ctx) => {
// Store current position
reviewOriginId = ctx.sessionManager.getLeafId();
// Get the root entry (first entry with null parent)
const entries = ctx.sessionManager.getEntries();
const rootEntry = entries.find(e => e.parentId === null);
if (!rootEntry) {
ctx.ui.notify("No root entry found in session", "error");
return;
}
// Navigate to root - this is headless (no UI), just moves leaf pointer
// This creates a new branch point from root in the same session
const result = await ctx.navigateTree(rootEntry.id, { summarize: false });
if (result.cancelled) return;
// Add marker entry at start of review branch
pi.appendEntry("review_start", {
originId: reviewOriginId,
startedAt: new Date().toISOString(),
});
ctx.ui.notify(
"Review branch started from root.\n" +
"Work normally, then use /end-review when done.",
"info"
);
},
});
pi.registerCommand("end-review", {
description: "Complete review and return to original position with summary",
handler: async (args, ctx) => {
if (!reviewOriginId) {
ctx.ui.notify("Not in a review branch (use /review first)", "error");
return;
}
// Get review branch to count entries
const reviewBranch = ctx.sessionManager.getBranch();
// Navigate back to origin
// summarize: true = auto-generates summary of the review branch
// The summary is added as a branch_summary entry at the navigation point
const result = await ctx.navigateTree(reviewOriginId, {
summarize: true,
customInstructions: args || undefined, // Optional custom summary instructions
});
if (result.cancelled) {
return;
}
// Add custom metadata entry after returning
pi.appendEntry("review_complete", {
reviewEntryCount: reviewBranch.length,
completedAt: new Date().toISOString(),
customInstructions: args || undefined,
});
ctx.ui.notify(
`Review complete! Returned to original position.\n` +
`Review had ${reviewBranch.length} entries.`,
"info"
);
reviewOriginId = undefined;
},
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment