Skip to content

Instantly share code, notes, and snippets.

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

  • Save badlogic/7e93f5012788b6d327f13e1249d36507 to your computer and use it in GitHub Desktop.

Select an option

Save badlogic/7e93f5012788b6d327f13e1249d36507 to your computer and use it in GitHub Desktop.
Pi extension: /review command - branch from root (parentId: null), work, return with summary
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 (null parent)
* /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 the first user message (sets leaf to null/root)
* - New entries will have parentId: null (new root branch)
* - 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 (where we'll return to)
reviewOriginId = ctx.sessionManager.getLeafId();
// Find the first user message (has parentId: null)
const entries = ctx.sessionManager.getEntries();
const firstUserMessage = entries.find(
e => e.type === "message" &&
e.message.role === "user" &&
e.parentId === null
);
if (!firstUserMessage) {
ctx.ui.notify("No root user message found in session", "error");
return;
}
// Navigate to first user message
// This will set leaf = firstUserMessage.parentId = null
// Next appendEntry() will create a new root branch (parentId: null)
const result = await ctx.navigateTree(firstUserMessage.id, { summarize: false });
if (result.cancelled) return;
// Add marker entry at start of review branch
// This entry will have parentId: null (root branch)
pi.appendEntry("review_start", {
originId: reviewOriginId,
startedAt: new Date().toISOString(),
});
ctx.ui.notify(
"Review branch started from root (parentId: null).\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
const result = await ctx.navigateTree(reviewOriginId, {
summarize: true,
customInstructions: args || undefined,
});
if (result.cancelled) {
return;
}
// Add completion metadata
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