Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/hook/commands/plannotator-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ allowed-tools: Bash(plannotator:*)

## Your task

Address the code review feedback above. The user has reviewed your changes in the Plannotator UI and provided specific annotations and comments.
If the review above contains feedback or annotations, address them. If no changes were requested, acknowledge and continue.
7 changes: 6 additions & 1 deletion apps/hook/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,12 @@ if (args[0] === "sessions") {
server.stop();

// Output feedback (captured by slash command)
console.log(result.feedback || "No feedback provided.");
if (result.approved) {
console.log("Code review completed — no changes requested.");
} else {
console.log(result.feedback);
console.log("\nThe reviewer has identified issues above. You must address all of them.");
}
process.exit(0);

} else if (args[0] === "annotate") {
Expand Down
8 changes: 6 additions & 2 deletions apps/opencode-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,11 @@ Do NOT proceed with implementation until your plan is approved.
const shouldSwitchAgent = result.agentSwitch && result.agentSwitch !== 'disabled';
const targetAgent = result.agentSwitch || 'build';

// Send feedback to agent - it will automatically respond and address it
const message = result.approved
? `# Code Review\n\nCode review completed — no changes requested.`
: `# Code Review Feedback\n\n${result.feedback}\n\nPlease address this feedback.`;

// Send feedback to agent
try {
await ctx.client.session.prompt({
path: { id: sessionId },
Expand All @@ -230,7 +234,7 @@ Do NOT proceed with implementation until your plan is approved.
parts: [
{
type: "text",
text: `# Code Review Feedback\n\n${result.feedback}\n\nPlease address this feedback.`,
text: message,
},
],
},
Expand Down
6 changes: 5 additions & 1 deletion apps/pi-extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,11 @@ export default function plannotator(pi: ExtensionAPI): void {
server.stop();

if (result.feedback) {
pi.sendUserMessage(`# Code Review Feedback\n\n${result.feedback}\n\nPlease address this feedback.`);
if (result.approved) {
pi.sendUserMessage(`# Code Review\n\nCode review completed — no changes requested.`);
} else {
pi.sendUserMessage(`# Code Review Feedback\n\n${result.feedback}\n\nPlease address this feedback.`);
}
} else {
ctx.ui.notify("Code review closed (no feedback).", "info");
}
Expand Down
11 changes: 7 additions & 4 deletions apps/pi-extension/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export interface GitContext {
export interface ReviewServerResult {
port: number;
url: string;
waitForDecision: () => Promise<{ feedback: string }>;
waitForDecision: () => Promise<{ approved: boolean; feedback: string }>;
stop: () => void;
}

Expand Down Expand Up @@ -415,8 +415,8 @@ export function startReviewServer(options: {
let currentGitRef = options.gitRef;
let currentDiffType: DiffType = options.diffType || "uncommitted";

let resolveDecision!: (result: { feedback: string }) => void;
const decisionPromise = new Promise<{ feedback: string }>((r) => {
let resolveDecision!: (result: { approved: boolean; feedback: string }) => void;
const decisionPromise = new Promise<{ approved: boolean; feedback: string }>((r) => {
resolveDecision = r;
});

Expand Down Expand Up @@ -446,7 +446,10 @@ export function startReviewServer(options: {
json(res, { rawPatch: currentPatch, gitRef: currentGitRef, diffType: currentDiffType });
} else if (url.pathname === "/api/feedback" && req.method === "POST") {
const body = await parseBody(req);
resolveDecision({ feedback: (body.feedback as string) || "" });
resolveDecision({
approved: (body.approved as boolean) ?? false,
feedback: (body.feedback as string) || "",
});
json(res, { ok: true });
} else {
html(res, options.htmlContent);
Expand Down
1 change: 1 addition & 0 deletions apps/review/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ server.stop();
console.log(
JSON.stringify({
gitRef: displayRef,
approved: result.approved,
feedback: result.feedback,
annotations: result.annotations,
}, null, 2)
Expand Down
6 changes: 3 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/review-editor/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ const ReviewApp: React.FC = () => {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
approved: false,
feedback: feedbackMarkdown,
annotations,
...(effectiveAgent && { agentSwitch: effectiveAgent }),
Expand All @@ -530,7 +531,8 @@ const ReviewApp: React.FC = () => {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
feedback: 'LGTM - no changes requested.',
approved: true,
feedback: 'LGTM - no changes requested.', // unused — integrations branch on `approved` flag
annotations: [],
}),
});
Expand Down
7 changes: 6 additions & 1 deletion packages/server/review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ export interface ReviewServerResult {
url: string;
/** Whether running in remote mode */
isRemote: boolean;
/** Wait for user feedback submission */
/** Wait for user review decision */
waitForDecision: () => Promise<{
approved: boolean;
feedback: string;
annotations: unknown[];
agentSwitch?: string;
Expand Down Expand Up @@ -101,11 +102,13 @@ export async function startReviewServer(

// Decision promise
let resolveDecision: (result: {
approved: boolean;
feedback: string;
annotations: unknown[];
agentSwitch?: string;
}) => void;
const decisionPromise = new Promise<{
approved: boolean;
feedback: string;
annotations: unknown[];
agentSwitch?: string;
Expand Down Expand Up @@ -259,13 +262,15 @@ export async function startReviewServer(
if (url.pathname === "/api/feedback" && req.method === "POST") {
try {
const body = (await req.json()) as {
approved?: boolean;
feedback: string;
annotations: unknown[];
agentSwitch?: string;
};

deleteDraft(draftKey);
resolveDecision({
approved: body.approved ?? false,
feedback: body.feedback || "",
annotations: body.annotations || [],
agentSwitch: body.agentSwitch,
Expand Down
Loading