diff --git a/apps/hook/server/index.ts b/apps/hook/server/index.ts index 797cc6e9..54d9d47a 100644 --- a/apps/hook/server/index.ts +++ b/apps/hook/server/index.ts @@ -12,6 +12,10 @@ * - Triggered by /review slash command * - Runs git diff, opens review UI * - Outputs feedback to stdout (captured by slash command) + * - Flags: + * - `--unstaged`: Show only unstaged changes (default: all uncommitted changes) + * - `--local`: Use local worktree for PR/MR reviews (default for PR URLs) + * - `--no-local`: Skip local worktree for PR/MR reviews * * 3. Annotate (`plannotator annotate `): * - Triggered by /plannotator-annotate slash command @@ -194,6 +198,8 @@ if (args[0] === "sessions") { if (localIdx !== -1) args.splice(localIdx, 1); const noLocalIdx = args.indexOf("--no-local"); if (noLocalIdx !== -1) args.splice(noLocalIdx, 1); + const unstagedIdx = args.indexOf("--unstaged"); + if (unstagedIdx !== -1) args.splice(unstagedIdx, 1); const urlArg = args[1]; const isPRMode = urlArg?.startsWith("http://") || urlArg?.startsWith("https://"); @@ -202,9 +208,9 @@ if (args[0] === "sessions") { let rawPatch: string; let gitRef: string; let diffError: string | undefined; + let initialDiffType: DiffType | undefined; let gitContext: Awaited> | undefined; let prMetadata: Awaited>["metadata"] | undefined; - let initialDiffType: DiffType | undefined; let agentCwd: string | undefined; let worktreeCleanup: (() => void | Promise) | undefined; @@ -379,7 +385,7 @@ if (args[0] === "sessions") { } else { // --- Local Review Mode --- gitContext = await getVcsContext(); - initialDiffType = gitContext.vcsType === "p4" ? "p4-default" : "uncommitted"; + initialDiffType = unstagedIdx !== -1 ? "unstaged" : "uncommitted"; const diffResult = await runVcsDiff(initialDiffType, gitContext.defaultBranch); rawPatch = diffResult.patch; gitRef = diffResult.label; diff --git a/apps/opencode-plugin/commands.ts b/apps/opencode-plugin/commands.ts index c2829f3c..0f1d336f 100644 --- a/apps/opencode-plugin/commands.ts +++ b/apps/opencode-plugin/commands.ts @@ -39,7 +39,15 @@ export async function handleReviewCommand( const { client, reviewHtmlContent, getSharingEnabled, getShareBaseUrl, directory } = deps; // @ts-ignore - Event properties contain arguments - const urlArg: string = event.properties?.arguments || ""; + const argsString: string = event.properties?.arguments || ""; + const args = argsString.split(" ").filter(Boolean); + + // Parse flags + const unstagedIdx = args.indexOf("--unstaged"); + const showUnstaged = unstagedIdx !== -1; + + // Find URL arg (first non-flag argument) + const urlArg = args.find(arg => !arg.startsWith("--")); const isPRMode = urlArg?.startsWith("http://") || urlArg?.startsWith("https://"); let rawPatch: string; @@ -78,7 +86,8 @@ export async function handleReviewCommand( client.app.log({ level: "info", message: "Opening code review UI..." }); gitContext = await getGitContext(directory); - const diffResult = await runGitDiffWithContext("uncommitted", gitContext); + const diffType: import("@plannotator/shared/review-core").DiffType = showUnstaged ? "unstaged" : "uncommitted"; + const diffResult = await runGitDiffWithContext(diffType, gitContext); rawPatch = diffResult.patch; gitRef = diffResult.label; diffError = diffResult.error; @@ -89,7 +98,7 @@ export async function handleReviewCommand( gitRef, error: diffError, origin: "opencode", - diffType: isPRMode ? undefined : "uncommitted", + diffType: isPRMode ? undefined : (showUnstaged ? "unstaged" : "uncommitted"), gitContext, prMetadata, sharingEnabled: await getSharingEnabled(), diff --git a/apps/pi-extension/index.ts b/apps/pi-extension/index.ts index 938da018..7d0bf96b 100644 --- a/apps/pi-extension/index.ts +++ b/apps/pi-extension/index.ts @@ -335,6 +335,16 @@ export default function plannotator(pi: ExtensionAPI): void { pi.registerCommand("plannotator-review", { description: "Open interactive code review for current changes or a PR URL", handler: async (args, ctx) => { + const argsString = args || ""; + const argsArray = argsString.split(" ").filter(Boolean); + + // Parse flags + const unstagedIdx = argsArray.indexOf("--unstaged"); + const showUnstaged = unstagedIdx !== -1; + + // Find URL arg (first non-flag argument) + const prUrl = argsArray.find(arg => !arg.startsWith("--")); + if (!hasReviewBrowserHtml()) { ctx.ui.notify( "Code review UI not available. Run 'bun run build' in the pi-extension directory.", @@ -344,9 +354,11 @@ export default function plannotator(pi: ExtensionAPI): void { } try { - const prUrl = args?.trim() || undefined; const isPRReview = prUrl?.startsWith("http://") || prUrl?.startsWith("https://"); - const result = await openCodeReview(ctx, { prUrl }); + const result = await openCodeReview(ctx, { + prUrl, + diffType: showUnstaged ? "unstaged" : undefined, + }); if (result.feedback) { if (result.approved) { pi.sendUserMessage(